Realign TextViews If Expands Past Container
I have a ListView, and I want to customize the layout of each item in the list so that it has a button on the right and a section to the left of the button that has multiple words that are TextViews (i.e. each TextView in the left hand side will be of one word). Here's a pict开发者_开发问答ure of what I mean:
Right now I have been able to successfully get the ButtonImage where I want it (with a defined width of 40dp). If I simply put the TextViews in a RelativeLayout, I noticed they stack on top of each other, so I added "android:layout_toRightOf"s in each of the TextViews accordingly. Obviously, this means that I will never have words below each other. I have set up the left side of this layout such that it has padding of 40dp to the right of it (so the TextViews weren't going behind the button or colliding into it). What happens is the TextViews will line up perfectly at the top and then the last few that can't squeeze in will expand vertically to fill the left box side. I would like to have the left box area (with the TextViews) set up such that, if a TextView is going to hit the right wall (technically the 40dp padding from the parent's right wall), it will be moved down and all the way to the left so the words read like a book. Also note that there will be anywhere from 1-5 TextViews (words) in this left hand side for any given item in the ListView. I'm pretty sure that, if I can get my layout the way I want it, I will never have to worry about the left hand side stacking higher than the button image (which would be an easily solvable problem anyhow). Here's my code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingRight="40dp"
android:id="@+id/kwds"
>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/first"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/third"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/second"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fourth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/third"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fifth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/fourth"
/>
</RelativeLayout>
<ImageButton android:id="@+id/bkmbtn"
android:src="@drawable/bkbtn"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
>
</ImageButton>
</RelativeLayout>
Before you guys ask, yes there really is a need to have a TextView per word (unfortunately ). If anything is unclear, let me know. And thank you for any help you can offer me! I really hope this is possible.
I worked on your code and made some modifications. Now its working fine as per your expectation.
Donot foget to vote.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
>
<ImageButton android:id="@+id/bkmbtn"
android:background="@drawable/a_thumb"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
>
</ImageButton>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingRight="40dp"
android:id="@+id/kwds"
android:layout_toLeftOf="@+id/bkmbtn"
android:orientation="horizontal"
>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="first"
android:background="#ffffff"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="second"
android:background="#ffffff"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/third"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/second"
android:text="third"
android:background="#ffffff"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fourth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fourth"
android:background="#ffffff"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fifth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fifth"
android:background="#ffffff"
/>
</LinearLayout>
</RelativeLayout>
Thanks Deepak
So I achieved this in the first natural way one would probably think of. I set up a 5x5 "table" of horizontally oriented LinearLayouts that stacked on top of each other to give it a TableLayout sort of feel. I did not use a TableLayout so I could easily have each LinearLayout "row" initially set to visibility of "gone" and make visible when needed (so it didn't give each entry a bloated feel). Here's an example of what I did:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingLeft="2dp"
android:paddingRight="40dp"
android:id="@+id/kwds"
android:orientation="vertical"
>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="@+id/kwdsone"
>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20sp"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/first"
android:textColor="#000000"
android:textSize="20sp"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/third"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/second"
android:textColor="#000000"
android:textSize="20sp"
/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="@+id/kwdstwo"
android:layout_below="@id/kwdsone"
android:visibility="gone"
>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fourth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20sp"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fifth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/fourth"
android:textColor="#000000"
android:textSize="20sp"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sixth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/fifth"
android:textColor="#000000"
android:textSize="20sp"
/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="@+id/kwdsthree"
android:layout_below="@id/kwdstwo"
android:visibility="gone"
>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/seventh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20sp"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/eighth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/seventh"
android:textColor="#000000"
android:textSize="20sp"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ninth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/eighth"
android:textColor="#000000"
android:textSize="20sp"
/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="@+id/kwdsfour"
android:layout_below="@id/kwdsthree"
android:visibility="gone"
>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tenth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20sp"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/eleventh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/tenth"
android:textColor="#000000"
android:textSize="20sp"
/>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/twelth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/eleventh"
android:textColor="#000000"
android:textSize="20sp"
/>
</LinearLayout>
</RelativeLayout>
In the example, I am using a 4x3 sort of "table" layout, but I changed this to a 5x5 (in the scenario that there may be 5 TextViews, all of which take up an entire row).
What I did next was to create a very simple sort of algorithm where I populate the first TextView of each row no matter what, but each TextView after that would be populated only if the maximum width of the container minus the width of the word that was going into the TextView and the width of the preceding already populated TextViews on the same row was greater than or equal to zero. That is, if the width of the next word would not overflow past the width of the parent. This is what it looked like:
Paint paint = new Paint();
// Convert the dps and sps to pixels with scale variable
float scale = getContext().getResources().getDisplayMetrics().density;
paint.setTextSize(20*scale);
//pWidth is the parent width, subtracting 55dps because of the button on the right of each entry
pWidth = parent.getWidth() - (55*scale);
//decide which index to set
if (indx==1){
if ((pWidth-(paint.measureText(((Spannable)((TextView)v.findViewById(R.id.first)).getText()).toString())+paint.measureText(word+"...")))<0)
indx=3;
}
if (indx==2){
if ((pWidth-(paint.measureText(((Spannable)((TextView)v.findViewById(R.id.first)).getText()).toString())+paint.measureText(((Spannable)((TextView)v.findViewById(R.id.second)).getText()).toString())+paint.measureText(word+"...")))<0)
indx=3;
}
if (indx==3){
v.findViewById(R.id.kwdstwo).setVisibility(View.VISIBLE);
if ((pWidth-paint.measureText(word+"..."))<0)
((TextView)v.findViewById(R.id.fourth)).setTextSize(16);
}
if (indx==4){
if ((pWidth-(paint.measureText(((Spannable)((TextView)v.findViewById(R.id.fourth)).getText()).toString())+paint.measureText(word+"...")))<0)
indx=6;
}
if (indx==5){
if ((pWidth-(paint.measureText(((Spannable)((TextView)v.findViewById(R.id.fourth)).getText()).toString())+paint.measureText(((Spannable)((TextView)v.findViewById(R.id.fifth)).getText()).toString())+paint.measureText(word+"...")))<0)
indx=6;
}
if (indx==6){
v.findViewById(R.id.kwdsthree).setVisibility(View.VISIBLE);
if ((pWidth-paint.measureText(word+"..."))<0)
((TextView)v.findViewById(R.id.seventh)).setTextSize(16);
}
if (indx==7){
if ((pWidth-(paint.measureText(((Spannable)((TextView)v.findViewById(R.id.seventh)).getText()).toString())+paint.measureText(word+"...")))<0)
indx=9;
}
if (indx==8){
if ((pWidth-(paint.measureText(((Spannable)((TextView)v.findViewById(R.id.seventh)).getText()).toString())+paint.measureText(((Spannable)((TextView)v.findViewById(R.id.eighth)).getText()).toString())+paint.measureText(word+"...")))<0)
indx=9;
}
if (indx==9){
v.findViewById(R.id.kwdsfour).setVisibility(View.VISIBLE);
if ((pWidth-paint.measureText(word+"..."))<0)
((TextView)v.findViewById(R.id.tenth)).setTextSize(16);
}
//based on the indx, populate the given TextView, again this is based on the 4x3 model and not the 5x5 model
if (indx==0)
index = (TextView) v.findViewById(R.id.first);
else if (indx==1)
index = (TextView) v.findViewById(R.id.second);
else if (indx==2)
index = (TextView) v.findViewById(R.id.third);
else if (indx==3)
index = (TextView) v.findViewById(R.id.fourth);
else if (indx==4)
index = (TextView) v.findViewById(R.id.fifth);
else if (indx==5)
index = (TextView) v.findViewById(R.id.sixth);
else if (indx==6)
index = (TextView) v.findViewById(R.id.seventh);
else if (indx==7)
index = (TextView) v.findViewById(R.id.eighth);
else if (indx==8)
index = (TextView) v.findViewById(R.id.ninth);
else if (indx==9)
index = (TextView) v.findViewById(R.id.tenth);
else if (indx==10)
index = (TextView) v.findViewById(R.id.eleventh);
else
index = (TextView) v.findViewById(R.id.twelth);
indx++;
Note that in this case, indx is a global variable defined in my class and set as 0. So, when this happens again for another entry in the ListView, indx is set back to 0. You must account for this if you use this method over and over again. If any of this does not make any sense, feel free to comment on here so I can clarify my answer.
精彩评论