0

I am up to something a little different from the standard custom listviews. I am having an activity which is responsible for displaying data retrieved from Parse.com database. The data contents are mostly in html format and may have any amount of text and images.

What I have already done:

  1. Retrieving the data from the database.
  2. Putting the data in a linear layout which is dynamically created according to the contents of the html.

What I wan to achieve:

  1. Add the layout to a listview as a row layout.

I have gone through a number of forums but I am still unable to find a solution using which I can inflate a listview without an xml layout and can assign my dynamic layout instead.

The activity source code:

public class MainActivity extends ActionBarActivity {

    ArrayList<String> originalContentList = new ArrayList<String>();
    ArrayList<String> reversedList = new ArrayList<String>();
    ImageView imageView1;
    Bitmap bitmap;
    RelativeLayout parent_layout;

    ParseObject user;

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

        parent_layout = (RelativeLayout) findViewById(R.id.parent_layout);

        login("xxx@xxx.com", "xxx");

        // reverseArraylist();
    }


    private void loopThroughArrayAndAttach(){
        LinearLayout llInner = new LinearLayout(this);
        llInner.setOrientation(LinearLayout.VERTICAL);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        parent_layout.addView(llInner);
        for (int i = 0; i < originalContentList.size(); i++) {

            if (hasNoImagess(originalContentList.get(i)) == true) {
                // No images.
                TextView myText = geneterTextView(originalContentList.get(i));
                llInner.addView(myText);

            } else {
                ImageView myImage = geneterImageView(originalContentList.get(i));
                llInner.addView(myImage);
            }
        }
    }

    public static boolean hasNoImagess(String contents){
        Document doc = Jsoup.parse(contents);
        Element element = doc.body();
        Elements elements = element.select("img");
        if (elements.isEmpty()) {
            return true;
        } else {
            return false;
        }
    }

    public ImageView geneterImageView(String imgContent){
        // Will need to run via background thread - like aysnc
        // Extract the image file via jsoup
        // Insert it into a imagevieww
        // Inser that into a layout.
        Log.d("IN IMAGE ", " " + imgContent);
        Document doc = Jsoup.parse(imgContent);
        Elements img = doc.getElementsByTag("img");
        Bitmap returnedBitmap = null;
        ImageView iv = new ImageView(this);
        for (Element el : img) {
            String src = el.absUrl("src");
            System.out.println("src attribute is : " + src);
            // new DownloadImageTask((ImageView)
            // findViewById(R.id.imageView1)).execute(src);
            try {
                //returnedBitmap = new LoadImage().execute(src).get();
                WorkerThread mWorkerThread = new WorkerThread(iv);
                mWorkerThread.execute(src);
                // imageView1.setImageBitmap(returnedBitmap);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
        }
//      ImageView iv = new ImageView(this);
        iv.setImageBitmap(returnedBitmap);
        return iv;
    }

    public TextView geneterTextView(String textContent){
        // Will need to run via background thread.
        Log.i("In TEXT ", " " + textContent);
        TextView tv = new TextView(this);
        tv.setText(Html.fromHtml(textContent));
        return tv;
    }


    private class WorkerThread extends AsyncTask<String, String, Bitmap> {
        private WeakReference<ImageView> imageViewReference;

        public WorkerThread(ImageView imageView) {
            super();
            imageViewReference = new WeakReference<ImageView>(imageView);
        }

        @Override
        protected Bitmap doInBackground(String... args) {
            // bitmap = null;
            try {
                bitmap = BitmapFactory.decodeStream((InputStream) new URL(args[0]).getContent());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            super.onPostExecute(result);
            if (result != null && imageViewReference.get() != null) {
                imageViewReference.get().setImageBitmap(result);
            }
        }

    }

    // to login to parse
    private void login(final String username, String password){
        ParseUser.logInInBackground(username, password, new LogInCallback() {
            @Override
            public void done(ParseUser user, ParseException e){

                if (e == null) {
                    // if login sucess
                    // Start intent
                    // loginSuccess();
                    Toast.makeText(MainActivity.this, "Success", Toast.LENGTH_SHORT).show();
                    CloudCallStudentPosts(user);

                } else {
                    Toast.makeText(MainActivity.this, "Failure", Toast.LENGTH_SHORT).show();
                }
            }
        });

    }

    // //to get data from parse
    public void CloudCallStudentPosts(ParseObject s){

        setRichStory(s);
    }

    private void setRichStory(ParseObject s){
        // Simialr to setStory, once implemented delete setStory()
        new AddStoryAsync(s).execute();
    }

    class AddStoryAsync extends AsyncTask<Void, Object, Void> {

        private static final String TAG = "LazyListView";
        ParseObject s;

        public AddStoryAsync(ParseObject s) {
            this.s = s;
            Log.w("In richStory", "ParseObject Id: " + s.getObjectId());
        }

        @Override
        protected void onPreExecute(){

        }

        @Override
        protected Void doInBackground(Void... unused){
            HashMap<String, Object> params = new HashMap<String, Object>();
            params.put("userid", this.s.getObjectId());
            params.put("skip", 0);
            ParseCloud.callFunctionInBackground("studentsPosts", params, new FunctionCallback<List<List<ParseObject>>>() {
                @Override
                public void done(List<List<ParseObject>> postList, com.parse.ParseException arg1){
                    if (postList == null) {
                    } else {
                        if (postList.size() > 0) {
                            // CustomWebView cwb;
                            for (int i = 0; i < postList.size(); i++) {
                                // final Post post = new Post();

                                if (postList.get(i).get(0).get("htmlContent") == null) {

                                    if (postList.get(i).get(0).getNumber("type") != null) {
                                        // post.setType(postList.get(i).get(0).getNumber("type"));
                                    }

                                    if (postList.get(i).get(0).getString("question") != null) {
                                        // post.setQuestion(postList.get(i).get(0).getString("question"));
                                    }

                                    if (postList.get(i).get(0).getString("textContent") != null) {
                                        // post.setQuestion(postList.get(i).get(0).getString("textContent"));
                                    }

                                    if (postList.get(i).get(0).getString("answer") != null) {
                                        // post.setAnswer(postList.get(i).get(0).getString("answer"));
                                    }

                                    if (postList.get(i).get(0).getCreatedAt() != null) {
                                        // post.setCreatedAt(postList.get(i).get(0).getCreatedAt());
                                    }

                                    // Need to re-get map and trip and photo
                                    // types
                                    if (postList.get(i).get(0).getParseFile("photo") != null)
                                        postList.get(i).get(0).getParseFile("photo").getDataInBackground(new GetDataCallback() {
                                            @Override
                                            public void done(byte[] imageByte, ParseException arg1){
                                                if (arg1 == null) {
                                                    Bitmap bmp = BitmapFactory.decodeByteArray(imageByte, 0, imageByte.length);
                                                    if (bmp == null) {

                                                    }

                                                }
                                            }

                                        });

                                    if (postList.get(i).get(0).getJSONArray("tripPoints") != null) {
                                        // post.setTripPoints(postList.get(i).get(0).getJSONArray("tripPoints"));
                                    }

                                    if (postList.get(i).get(0).getParseGeoPoint("location") != null) {
                                        // post.setLocation(postList.get(i).get(0).getParseGeoPoint("location"));
                                    }

                                    // publishProgress(post);
                                }

                                if (postList.get(i).get(0).get("htmlContent") != null) {
                                    Log.e("htmlContent parse", postList.get(i).get(0).get("htmlContent").toString());
                                    // Parse HTML String using JSoup library
                                    String HTMLSTring = postList.get(i).get(0).get("htmlContent").toString();

                                    Document html = Jsoup.parse(HTMLSTring);

                                    Elements paragraphs = html.getElementsByTag("p");
                                    for (org.jsoup.nodes.Element paragraph : paragraphs) {
                                        String paragraphText = paragraph.toString();
                                        Log.e("paragraphText", paragraphText);
                                        originalContentList.add(paragraphText);
                                    }

                                    loopThroughArrayAndAttach();
                                }
                                // publishProgress(post);
                                // This is where we publish

                            }
                        }
                    }
                }

            });
            return (null);
        }

        @Override
        protected void onProgressUpdate(Object... object){

            Log.w("onProgressUpdate ", " " + object[0].getClass());

            Log.w("adding to arrayPostList ", " " + object[0].getClass());

        }

        @Override
        protected void onPostExecute(Void unused){
        }

    }

}

The method loopThroughArrayAndAttach() is generating the linearlayout programmatically and adding imageviews and textviews to it dynamically. For now the linearlayout is attached to the parent layout which, which needs to be substituted with a listview.

The layout:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scrollView1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        android:id="@+id/parent_layout">
    </RelativeLayout>

</ScrollView>

How to achieve the desired output?

kittu88
  • 2,451
  • 5
  • 40
  • 80
  • `inflate a listview without an xml layout and can assign my dynamic layout instead.` you do not understand. `inflate` means to parse the XML layout and create the view heirarchy. All you need to do is `Listview myListView = new ListView(this)` or similar. There is nothing magical and layout XML. It is just data to describe to the inflater what objects to create and which properties to set. See this http://stackoverflow.com/questions/22897942/making-dynamic-layout-for-each-row-in-listview-in-android – Simon Jan 20 '15 at 08:15
  • @Simon I have gone through that post already but could not figure out what is to be done exactly. As I could see convertView = mInflater.inflate(R.layout.sample, null); and some other views with ids which are supposed to be predefined in the xml. – kittu88 Jan 20 '15 at 08:19

0 Answers0