momo
momo

Reputation: 3935

Android layout - align to right without wrapping and reserving space

What I thought would be a fairly straightforward layout is not turning out to be.

I have several rows in a linear layout.

Each row has a "title", a "tag" and a "description".

The description appears below the title and tag and is no problem.

The title is of indeterminate length and should be aligned to top left. The tag should appear appear aligned to the right of the title (not necessarily the right edge of the parent, if the title is short). If there's not enough room for both on a single line, the title should wrap and leave space for the tag.

The tag has it's own style and behavior, and must be a separate element from the title.

In my limited experience, I've had the most luck with RelativeLayouts, so that was my first try:

import android.content.Context;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class ExampleRow extends RelativeLayout {

    private TextView title;
    private TextView description;
    private TextView tag;

    public ExampleRow(Context context) {

        super(context);

        LayoutParams lp;        

        lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        title = new TextView(context);
        title.setId(1);
        addView(title, lp);                 

        lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
        lp.addRule(RelativeLayout.BELOW, title.getId());
        description = new TextView(context);
        description.setId(2);
        addView(description, lp);       

        lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        lp.addRule(RelativeLayout.RIGHT_OF, title.getId());
        lp.addRule(RelativeLayout.ABOVE, description.getId());
        lp.setMargins(20, 0, 0, 0);
        tag = new TextView(context);
        addView(tag, lp);

    }
}

Long titles would force the tag off-screen.

I then tried nested LinearLayouts - the main container as a LinearLayout with vertical orientation, that had a "top row" that was a horizontal LinearLayout containing the title and the tag, and the bottom "row" being the description. That had the same issue described above.

Next I tried TableLayout, with 2 TableRows, but this not only failed but also showed strange quirks like not rendering certain rows at all, for reasons I don't understand. The documentation on TableLayout and TableRow seems a little sparse, and I wasn't able to find the Java equivalents of XML fields dealing with columns.

The layout needs to be in Java, not XML, for reasons too long and uninteresting to mention.

Any insight is appreciated.

TYIA.

/EDIT

to clarify the requirement, the best example I can think of would be in HTML.

<table>
  <tr>
    <td>title</td>
    <td>tag</td>
  </tr>
  <tr>
    <td colspan="2">description...</td>
  </tr>
</table>

the tag is always to the right of the title, but only as far right as it needs to be (depending on title width). the title would wrap once it forced the tag to the most extreme right.

Upvotes: 0

Views: 372

Answers (2)

user
user

Reputation: 87074

I think this is the layout you're after:

public class TableLayoutCustom extends TableLayout {

    public TableLayoutCustom(Context context) {
        super(context);

        this.setColumnShrinkable(0, true);
        this.setColumnStretchable(1, true);

        TableRow row1 = new TableRow(context);

        TableRow.LayoutParams lp = new TableRow.LayoutParams(
                LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
        TextView title = new TextView(context);
        title.setText("Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum ");

        title.setId(1);
        row1.addView(title, lp);

        lp.setMargins(20, 0, 0, 0);
        TextView tag = new TextView(context);
        tag.setText("TAG ME");
        row1.addView(tag, lp);

        this.addView(row1);

        TableRow row2 = new TableRow(context);
        TableRow.LayoutParams tlp = new TableRow.LayoutParams(
                LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
        tlp.span = 2;
        TextView description = new TextView(context);
        description.setText("Description here");
        description.setId(2);
        row2.addView(description, tlp);

        this.addView(row2);
    }

}

If you change the text on the title to something shorter you will see that the tag "follows" the title.

Upvotes: 1

momo
momo

Reputation: 3935

after a few more tries, including a linear layout with a table layout enclosing the title and tag, and the description as a child of the linear layout, i'll post what I'm using for now.

while this comes close, i'm still open to a better answer:

using right margin on the title and negative left margin of an equal amount on the tag does accomplish the basic idea, it assumes I know the size of the tag. If I allow say 100 pixels, and the tag text is longer than that, it'll wrap. This isn't a huge deal for this particular setup (since I have a predictable set of tags), I'd still be interested to know the "correct" approach.

Upvotes: 0

Related Questions