Android's RelativeLayout seems broken - android

I'm working on a layout where I use a ListView with RelativeLayout line items. The lineitems themselves are not displaying correctly.
The issue is that the txtVideoDuration TextView is drawn at the top of the line item instead of the bottom. Because of this the txtVideoTitle gets a height of 0. As you can see in the XML the txtVideoDuration is supposed to be clamped to the bottom of the ListView.
My goal is to have the layout resemble the tutorial that google gave me. Example: http://android-developers.blogspot.com/2009/02/android-layout-tricks-1.html
I'm using Android 2.0.1. I've even plugged in the example layout with out modification into the ListView and the same behavior happens.
<?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="?android:attr/listPreferredItemHeight"
android:padding="6dip">
<ImageView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="#+id/imgVideoThumbnail"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:minHeight="64dip"
android:layout_marginRight="6dip"
android:src="#drawable/icon" />
<TextView
android:id="#+id/txtVideoDuration"
android:layout_width="fill_parent"
android:layout_height="26dip"
android:layout_toRightOf="#+id/imgVideoThumbnail"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:singleLine="true"
android:ellipsize="marquee"
android:text="0:00:00" />
<TextView
android:id="#+id/txtVideoTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/imgVideoThumbnail"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_above="#+id/txtVideoDuration"
android:layout_alignWithParentIfMissing="true"
android:gravity="center_vertical"
android:text="[Title]"
android:textColor="#FFFFFF" />
</RelativeLayout>
This simple case works. This is the root XML layout for the activity. The buggy code at the top is the line items in the list view. It seems that the ListView itself is breaking it.
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/listVideoCatalog"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<TextView
android:id="#+id/txtName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Hello World" />
</RelativeLayout>
</merge>
This is the getView Code that inflates the line item into the ListView.
static class ViewHolder
{
TextView txtTitle;
ImageView imgThumbnail;
TextView txtDuration;
Uri videoLocation;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if(convertView == null)
{
LayoutInflater li = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(R.layout.listitem_videolineitem, null);
holder = new ViewHolder();
holder.txtDuration = (TextView) convertView.findViewById(R.id.txtVideoDuration);
holder.txtTitle = (TextView) convertView.findViewById(R.id.txtVideoTitle);
holder.imgThumbnail = (ImageView) convertView.findViewById(R.id.imgVideoThumbnail);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
VideoFile video = this.videos.get(position);
holder.txtDuration.setText(millisToTimestamp(video.videoDuration));
holder.txtTitle.setText(video.videoTitle);
// Some debugger visual code.
holder.txtDuration.setBackgroundColor(Color.GREEN);
holder.txtTitle.setBackgroundColor(Color.CYAN);
return convertView;
}

This was answered in the comment of the accepted answer. Just to make it clear, this is the answer:
Change
li.inflate(R.layout.listitem_videolineitem, null);
to
li.inflate(R.layout.listitem_videolineitem, parent, false);

How are you inflating your row views that are "buggy"? Can you provide a code snippet?
Also, android:orientation="vertical" is not valid for RelativeLayout.

Related

Want to align linearlayout inside another, but setGravity() doesn`t work

I am trying to align a linear layout inside another linear layout programmatically, but setGravity(Gravity.RIGHT) doesn`t work.
I know the differences between gravity and layout_gravity.
Here's the xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="#+id/initial_wrapper"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:id="#+id/conversationwrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/bubble_yellow"
>
<TextView
android:id="#+id/messagecontent_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dip"
android:paddingLeft="10dip"
android:text="Message_content"
android:textSize="15dp" />
<TextView
android:id="#+id/timestamp_tv"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="HH:MM"
android:ems="2"
android:textSize="12dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
And the code of getView() in my Adapter:
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.listitem_conversation, parent, false);
}
wrapper = (LinearLayout) row.findViewById(R.id.conversationwrapper);
initial_wrapper = (LinearLayout) row.findViewById(R.id.initial_wrapper);
time = (TextView) row.findViewById(R.id.timestamp_tv);
Message coment = getItem(position);
content = (TextView)row.findViewById(R.id.messagecontent_tv);
content.setText(coment.content);
time.setText(getCurrentTimeStamp());
wrapper.setBackgroundResource(!coment.mine ? R.drawable.bubble_yellow : R.drawable.bubble_green);
initial_wrapper.setGravity(!coment.mine ? Gravity.LEFT : Gravity.RIGHT);
return row;
}
But it always happen to be on the left, even when the image is green.
The strange thing is that if I type
android:gravity="right"
inside initial_wrapper, It works in the preview but not in the device.
I'm using a Moto G and a Nexus 5, but neither of them work
The problem can be here : android:layout_width="fill_parent", how you supose to set android:gravity="right" here, if your layout is filling whole parent? You should try to use
<LinearLayout
android:id="#+id/initial_wrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
instead of :
<LinearLayout
android:id="#+id/initial_wrapper"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
do this
<LinearLayout
android:id="#+id/initial_wrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity = "left"
>
in your getView() do this
LinearLayout.LayoutParams lp = initial_wrapper.getLayoutParams();//will need to casting
lp.gravity= Gravity.RIGHT; // this is the important part
initial_wrapper.setLayoutParams(lp);
hope it helps

Reset TextView position in row of Listview for Android Application

I am using ListView to display some data. The data is shown in TextView. String length which is shown can vary. so the textview which is shown changes its positions depending upon the length of the string. The problem I am facing is
Suppose there are 5 rows. For Row 3 if the text is long, the position of textview showing the text adjusts to show the content. However, textview positions of other rows also changes even if the text is smaller. This has something to do with ListView row caching I am not able to figure out how to reset the row.
Row Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="100dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="#dimen/text_margin_bottom"
android:orientation="horizontal">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/id1"
android:textSize="#dimen/textsize_content3" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/id2"
android:textSize="#dimen/textsize_content3" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="#dimen/text_margin_bottom"
android:orientation="horizontal">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/id3"
android:textSize="#dimen/textsize_content3" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/id4"
android:textSize="#dimen/textsize_content3" />
</LinearLayout>
</LinearLayout>
GetView Code
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
ShowData metaData = getItem(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.row, parent, false);
holder = new ViewHolder();
holder.id1 = (TextView) convertView
.findViewById(R.id.id1);
holder.id2 = (TextView) convertView
.findViewById(R.id.id2);
holder.id3 = (TextView) convertView
.findViewById(R.id.id3);
holder.id3 = (TextView) convertView
.findViewById(R.id.id4);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
convertView.invalidate();
holder.id1.setText(metaData.id1);
holder.id2.setText(metaData.id2);
holder.id3.setText(metaData.id3);
holder.id4.setText(metaData.id4);
return convertView;
}
How to reset the listview row?
As you mentioned, your TextViews are sizing vertically due to the wrap_content values for their layout_heights. It seems that when Views are recycled in ListViews (and, most likely, all AdapterViews), no layout is automatically triggered, so the TextViews will retain their previous heights. Calling requestLayout() on them will trigger a layout event, during which the TextViews will adjust to their new contents.

List Fragment not Clickable

I have a class extending a list fragment, and for some reason, the fragment is not receiving the list item clicks. I have narrowed down the problem to the row items, but I still can't see what the problem is. Here is my XML. Any ideas?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:focusable="true">
<ImageButton
android:id="#+id/image_button"
android:layout_width="120px"
android:layout_height="120px"
android:scaleType="fitXY"/>
<TextView
android:id="#+id/text_view1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"/>
Here is how I inflate this layout in my custom adapter:
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = vi.inflate(R.layout.list_item, parent, false);
T t = list.get(position);
TextView tv1 = (TextView) view.findViewById(R.id.text_view1);
tv1.setText(t.getName());
ImageButton image= (ImageButton) view.findViewById(R.id.image_button);
image.setBackgroundColor(Color.parseColor("blue"));
return view;
}
I don't see any reason for android:focusable="true" in your parent layout, unless you're trying to achieve what seems to be your problem : switch focus from the list to the list item. Remove that element from your layout and it will work fine.
Revised version :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:focusable="true">
<ImageButton
android:id="#+id/image_button"
android:layout_width="120px"
android:layout_height="120px"
android:scaleType="fitXY"/>
<TextView
android:id="#+id/text_view1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"/>

Android ImageView dynamic width and height

I have a horizontal list of images loaded from a url. So i have an ImageLoader, then an Adapter then my Activity. My xml layouts looks like this:
mainlayout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.devsmart.android.ui.HorizontalListView
android:id="#+id/hlist_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="always" >
</com.devsmart.android.ui.HorizontalListView>
</LinearLayout>
Then my list.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:translationY="200dp" > <!-- make this dynamic -->
<FrameLayout
android:id="#+id/mainlayout"
android:layout_height="wrap_content"
android:layout_width="wrap_content" >
<ImageView
android:id="#+id/prof_pic"
android:clickable="true"
android:adjustViewBounds="true"
android:layout_width="360dp"
android:layout_height="360dp" />
<ProgressBar
android:id="#+id/img_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
<TextView
android:id="#+id/sname"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold" />
<TextView
android:id="#+id/sdesc"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
With this layout, the result is Figure A. The gray broken line is the imageView, we can't actually see it but only those images(green box). What i want to achieve is the one in Figure B.
So, to somewhat solve this i tried adding in my imageView
<ImageView
android:id="#+id/prof_pic"
android:clickable="true"
android:adjustViewBounds="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="360dp"
android:maxHeight="360dp"
android:minHeight="240dp"
android:minWidth="240dp"
/>
But what happened is that, by the time i open the application, my image list looks like Figure A. But when a scroll along the images, it adjusted to somewhat look like Figure B. But when i scroll back to the first image, only the first have of the image will only be show or sometimes, my image list starts at my second image. This is really crazy.
Is there any way where i can achieve Figure B without destroying my list of images or at the start of the app, it already displays like Figure B?
EDIT:
This is how my Adapter looks like:
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder = null;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if(convertView == null){
convertView = inflater.inflate(R.layout.list_layout, null);
holder = new ViewHolder();
holder.txtShopName = (TextView) convertView.findViewById(R.id.shop_name);
holder.txtDesc = (TextView) convertView.findViewById(R.id.desc);
holder.imageView = (ImageView) convertView.findViewById(R.id.prof_pic);
holder.progBar = (ProgressBar) convertView.findViewById(R.id.img_progress);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
imageLoader=new ImageLoader(context.getApplicationContext(), holder.progBar);
SRowItem sItem = (SRowItem) getItem(position);
holder.txtName.setText(sItem.getShopName());
holder.txtDesc.setText(sItem.getShopDesc());
imageLoader.DisplayImage(sItem.getImageUrl(), holder.imageView);
return convertView;
}
Try something like this :
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, height);
ImageView imageView = (ImageView) LayoutInflater.from(context).inflate(R.layout.image, null);
imageView.setLayoutParams(params);

How to set custom list view item's height...?

I have a custom list view which contains two text views and on button.
I have customized the button style.
In the list view each row is not fit to show my button properly.
I want to change the list item's height.
How can i do that..?
This is my list view.
<ListView android:layout_width="fill_parent"
android:scrollbars="none" android:footerDividersEnabled="false"
android:minHeight="50dp"
android:listSelector="#00000000" android:dividerHeight="0px"
android:divider="#00000000" android:layout_height="fill_parent"
android:layout_marginLeft="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="5dp" android:id="#+id/list_view"
android:cacheColorHint="#00000000" android:background="#00000000" />
my custom view xml
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:layout_width="150dp"
android:layout_height="wrap_content"
android:textColor="#808080" android:text="Subtitle 2" android:id="#+id/text1"
android:layout_marginLeft="5dp"
android:singleLine="true"/>
<TextView android:layout_width="60dp"
android:layout_height="wrap_content"
android:textColor="#808080" android:text="$ 00.00" android:id="#+id/text2"
android:singleLine="true"/>
<Button android:layout_width="80dp" android:layout_height="25dp"
android:background="#drawable/type10_subbg" android:text="Add"
android:textSize="20dp" android:textStyle="bold" android:textColor="#153E7E"
android:id="#+id/add" />
</LinearLayout>
Here is my getView.
#SuppressWarnings("unchecked")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
pos = position;
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.type10_sub, null);
holder.text1 = (TextView) convertView.findViewById(R.id.text1);
holder.text2 = (TextView) convertView.findViewById(R.id.text2);
holder.add = (Button) convertView.findViewById(R.id.add);
holder.add.setTag(String.valueOf(position));
holder.add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Button b = (Button)v;
int tag = Integer.valueOf((String)b.getTag());
System.out.println("Added at "+tag);
System.out.println("Data = "+((HashMap<String,Object>)list.get(tag)).get("text1").toString());
System.out.println("Price = "+((HashMap<String,Object>)list.get(tag)).get("text2").toString()); }
}); holder.text1.setText(((HashMap<String,Object>)list.get(position)).get("text1").toString());
holder.text2.setText(((HashMap<String,Object>)list.get(position)).get("text2").toString());
convertView.setTag(holder);
return convertView;
}
Thanks in advance....!
convertedview.setlayoutparams(new Listview.setlayoutparams(width, height));
First put LinearLayout instead of ListView
and then edit that to ListView otherwise it will not work. This is the trick.
set minHeight in R.layout.type10_sub elements
Its very easy to hardcode in a new height for the custom view simply specify the layout_height for the highest level item, in this case the LinearLayout. Below I've shown how to set it to 100dp
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="fill_parent"
android:layout_height="100dp">
....
</LinearLayout>
In linear layout give android:layout_height="100dp" instead of wrap_content
use:
if(convertView == null){
convertView = inflater.inflate(R.layout.type10_sub, parent);
}

Categories

Resources