How to align strings to use in a listview?

Asked

Viewed 1,894 times

13

In my Android project I need to create a table with a listview but the data always comes misaligned. I place each record of my database in a position of a string array to use it in listview. The method I use to try to align is this:

public static String CompletaEspacos(String palavra) {
    if (palavra == null) {
        palavra = "";
    }
    String retorno = "";

    palavra = palavra.trim();

    if(palavra.length()>=19){
        retorno = palavra.substring(0,19);
    } else {
        retorno = String.format("%-19s", palavra);
    }       
    return retorno;
}

In other words, each "cell" of the table contains a word up to its 19th character or a smaller word with spaces until it reaches 19. This is my logic but it is not working. What is the best way to create the strings of an array to mount an aligned table in a listview in Java.

  • 3

    Can you explain better what you mean by "it’s not working"?

  • 3

    I’m not familiar with Android programming, but it makes a difference whether it’s on it or any Java device?

  • 1

    Wouldn’t it be better to use Listview’s own alignment parameters? With android:textAlignment="center".

  • 1

    bfavaretto, I would like the data to be aligned to form a table, however they are not aligned with the title

  • @anovaesneto, therefore, I think it is better to make a Tablelayout behave like a Listview, this can be seen here

  • 1

    @According to what I understood from his example he used a certain number of rows in the table. but I search the data of my listview in the database, I do not know how many lines will be.

  • @anovaesneto could send an image to demonstrate how his list is getting.

  • @anovaesneto an image would be nice, but it seems to me that you are using the standard font that has different widths for each character. You need to configure this Listview to use Droid Sans Mono (monospace)

  • This is the kind of solution I would rather leave in the bank rather than the view treat.

Show 4 more comments

2 answers

11


For this you need to use monospaced fonts, such as Courier (or the native Droid Sans Mono, as pointed out by @Alexandre Marcondes).

Monospaced fonts, unlike proportional fonts, are those where all letters have the same widths. See just the comparison:

Example 1

XMILSW
WWMWMW
i01 . m

Example 2

XMILSW
WWMWMW
i01 .m

Note that in the first case the letters do not align and in the second yes.

Take a look at the documentation of typeface MONOSPACE to see some options in this direction.

Consider the Grid View as an alternative. Grid View allows you to have multiple separate columns, aligned independently of the content.

  • As the question that was asked later is being marked as duplicate (with reason), I passed the answer here. (duplicate in http://answall.com/questions/2509/problema-com-alignment-string )

  • I hadn’t thought of the monospace, case to ListView have only one column, I think this is the best solution.

  • 2

    People I managed to do what I wanted putting the Gridview and using an adapter I inherited from Basedapter.

8

Based on the comments, I could understand that what you want is a dynamic Listview. For this, you will need to create a Adapter specifically for this and fill in each row of the ListView with a specific xml, suitable for aligning.

To help, I found this tutorial that the author himself writes is a good solution when it will fill a ListView with data from a database.

I edited his code to get a little more generic, I’ll split it into parts:

List class

package com.dynalist;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MyList extends Activity {
    /** Called when the activity is first created. */
    ListView listView;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        listView = (ListView) findViewById(R.id.lv_country);
        listView.setAdapter(new EfficientAdapter(this));
    }
    private static class EfficientAdapter extends BaseAdapter {
        private LayoutInflater mInflater;

        public EfficientAdapter(Context context) {
            mInflater = LayoutInflater.from(context);
        }

        public int getCount() {
            return CountriesList.abbreviations.length;
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.two_col_row, null);
                holder = new ViewHolder();
                holder.text1 = (TextView) convertView
                        .findViewById(R.id.TextView01);
                holder.text2 = (TextView) convertView
                        .findViewById(R.id.TextView02);

                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.text1.setText(CountriesList.abbreviations[position]);
            holder.text2.setText(CountriesList.countries[position]);

            return convertView;
        }

        static class ViewHolder {
            TextView text1;
            TextView text2;
        }
    }
}

Distrinchando this class we have:

private ListView listView;
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    listView = (ListView) findViewById(R.id.lv_country);
    listView.setAdapter(new EfficientAdapter(this));
}

In this snippet he creates the list from a predefined layout and saves the reference in the variable ListView to use later, together with it he assigns a Adapter for this list, which is defined internally of the class in this example (for reasons of code organization this is not the most correct way to do, what is correct would be to encapsulate the class and import it). The Adapter is responsible for the content of the list when you assign a Adapter, you are assigning the "data background". Taken from the documentation itself of Listview by Google Developers, dealing with the parameter adapter of the kind ListAdapter:

The Listadapter which is Responsible for maintaining the data backing this list and for producing a view to represent an item in that data set.

In free translation:

The Listadapter which will be responsible for maintaining the data from this list and for producing a view to represent an item that is in the dataset.

Within the class EfficientAdapter it creates some auxiliary methods, but the main method is the getView:

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.two_col_row, null);
        holder = new ViewHolder();
        holder.text1 = (TextView) convertView
            .findViewById(R.id.TextView01);
        holder.text2 = (TextView) convertView
            .findViewById(R.id.TextView02);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    } 
    holder.text1.setText(CountriesList.abbreviations[position]);
    holder.text2.setText(CountriesList.countries[position]); 
    return convertView;
}

With this method it initializes A LINE of ListView, as previously treated. Each line is a view with two TextView of the layout two_col_rol, which will be presented below.

But how he populates the list?

The "trick" is in the methods getCount, getItem and getItemId, which makes it iterate through all its entries (in this case a list of country abbreviations), allowing it, from a vector, to populate the entire list with the getView.

XML of the list

In the example it puts a header and a "line of subtitles", I preferred to treat only the XMLof ListView for the answer not to be more extensive yet.

<?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"
    android:background="#ffccd0"
    >
    <ListView
        android:id="@+id/lv_country"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:cacheColorHint="#00000000">
    </ListView>
</LinearLayout>

All he does is one ListView normal that does not need much attention, since it is a basic list, there is not much to comment on.

The view of each line in the List

Here is where is the other "secret" of making an aligned dynamic list. As each line is a View, just align the text from the android:gravity as shown in XML down below:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:gravity="left|center"
    android:layout_width="wrap_content"
    android:paddingBottom="10px"
    android:paddingTop="10px"
    android:paddingLeft="3px">
     <!-- Coluna 1 -->
     <TextView
        android:id="@+id/TextView01"
        android:layout_width="70dip"
        android:layout_height="wrap_content"
        android:gravity="left"
        android:textSize="15dip"
        android:textStyle="bold"
        android:textColor="#d08021"
        android:paddingLeft="20dip"/>
     <!--Coluna 2-->
     <TextView
        android:id="@+id/TextView02"
        android:layout_width="200dip"
        android:layout_height="wrap_content"
        android:gravity="left"
        android:layout_marginLeft="10dip"
        android:textSize="15dip"
        android:textStyle="bold"
        android:textColor="#7f0000"/>
</LinearLayout>

As, in your case, only one column is required, it is enough to leave a TextView, with the formatting you want.

  • I will then test the code of this tutorial and anything warning you

  • 2

    @Felipe-Velar, welcome to SOPT, please post the tutorial code you sent, how to use an Adapter, and keep the link as a reference, link may become obsolete, responses should not fall along with the link

  • 1

    @Ernandes, I think the answer is a little better now. (:

  • ball show!!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.