VanessaF
VanessaF

Reputation: 793

Android: SpannableString with correctly formated numbers

I would like to have a list of instructions that are correctly numbered in an enumeration. For that I use the SpannableString and I have the following code:

//Get string array from a sqLite Database
String [] instructions = MainActivity.sqLiteDataba.getPreparationInstructions(item);

//Create Spannable String Builder
int numberOfCurrentInstruction = 1;
SpannableStringBuilder builderInstructions =  new SpannableStringBuilder();
for (int i =0; i<instructions.length;i++) {
    if(instructions[i] == null ) {
        continue;
    }

    builderInstructions.append(numberOfCurrentInstruction + ". " + instructions[i] + "\n");
    numberOfCurrentInstruction++;
}

The output in a textview (called in a Fragment) does not look like the desired way, as you can see in the screenshot: enter image description here

I would like the numbers to serve as "bullet points" meaning that if there is a linebreak in the textView, the following text should not start under the number but with a little bit of space. Any idea how I can do that?

Update: I tried the suggested approach posted below (Darkman) with the layout inflator but unfortunately only the very first item is being displayed. Here is the code from inside a Fragment:

    String [] instructions = MainActivity.sqLiteDB.getPreparationInstructions(item);

    
    int numberOfCurrentInstruction = 1;
    ViewGroup main = getView().findViewById(R.id.main);
    LayoutInflater inflator = getLayoutInflater();

    for (int i =0; i<instructions.length;i++) {
        if(instructions[i] == null ) {
            continue;

        }

        ViewGroup mainLayout = (ViewGroup) inflator.inflate(R.layout.custom, main, true);
        ViewGroup customLayout = (ViewGroup) mainLayout.getChildAt(i);


        TextView num = (TextView) customLayout.getChildAt(0);
        TextView text = (TextView) customLayout.getChildAt(1);
        num.setText((numberOfCurrentInstruction) + ".");
        text.setText(instructions[i]);
        numberOfCurrentInstruction++;
    }

Here is the custom.xml file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:gravity="right"
        android:layout_marginTop="@dimen/_2sdp"
        android:layout_marginLeft="@dimen/_5sdp"
        android:textSize="@dimen/_7ssp"/>

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:gravity="left"
        android:layout_marginTop="@dimen/_2sdp"
        android:layout_marginLeft="@dimen/_2sdp"
        android:layout_marginRight="@dimen/_5sdp"
        android:textSize="@dimen/_7ssp"/>
</LinearLayout>

And the main.xml is inside a xml file for a fragment and looks like this:

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:id="@+id/main">


    </LinearLayout>

The array instructions has 5 elements in it and none of them is null and the for loop is executed 5 times (I checked this by using LogTag). However, only the first instruction is displayed and the others not. Any idea what the problem might be?

Upvotes: 2

Views: 705

Answers (2)

Darkman
Darkman

Reputation: 2991

You can achieve that by using two TextViews via XML like the following example.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="#333333"
    android:orientation="vertical"
    android:id="@+id/main">

</LinearLayout>

custom.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:gravity="right"
        android:layout_marginLeft="10dp"/>

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:gravity="left"
        android:layout_marginRight="10dp"/>

</LinearLayout>

MainActivity.java

public class MainActivity extends Activity 
{
    private static final String[] str = {
        "Instruction 1: This is the first instruction that you have to do.",
        "Instruction 2: This is the second instruction that you have to do.",
        "Instruction 3: This is the third instruction that you have to do."
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
        
        ViewGroup main = findViewById(R.id.main);
        LayoutInflater inflator = getLayoutInflater();
        
        for(int i=0; i<3; i++) {
            ViewGroup mainLayout = (ViewGroup) inflator.inflate(R.layout.custom, main, true);
            ViewGroup customLayout = (ViewGroup) mainLayout.getChildAt(i);
            TextView num = (TextView) customLayout.getChildAt(0);
            TextView text = (TextView) customLayout.getChildAt(1);
            num.setText((i+1) + ".");
            text.setText(str[i]);
        }
    }
}

Output: enter image description here

Upvotes: 1

IlyaFromRussia
IlyaFromRussia

Reputation: 102

If you use fixed-space font add several spaces after \n. If you use monospace font adding spaces isn`t best way. In this case you can add symbols "1", "2" etc instead of spaces and set color for this symbols like background color.

Upvotes: 0

Related Questions