4

I am struggling to debug a weird UI glitch for listviews in my android app. 99% of the time everything looks and works like it should, but every now and then my listviews behave strangely. When you restart the app the listview looks normal again.

Does anyone know if this is a known android bug?

The fact that it only happens at random (I have tried to figure out a pattern and cant) scares me. I havent been able to find anything online regarding similar issues. Hopefully I've just been googling the wrong search-terms.

Any advice/help would be much appreciated.

Thanks in advance.

What the Listview usually looks like:

What the listview looks like most of the time

What the listview looks like every now and then:

What happens every now and then

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="horizontal"
          android:layout_width="match_parent"
          android:layout_height="@dimen/tile_height_padded"
          android:descendantFocusability="blocksDescendants"
          android:layout_margin="0dp"
          android:padding="@dimen/padding_list">

<!--This is the clickable background of the item-->
<ImageView
        android:id="@+id/imageview_poi_tile_detail_button_detail"
        android:background="@color/ca"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="0dp"
        android:layout_toLeftOf="@+id/imageview_poi_tile_map_button"/>

<!--This is the Grey vertical line next to the icon on the left-->
<ImageView
    android:id="@+id/delimiter_poi_tile"
    android:layout_width="@dimen/delimiter_size"
    android:layout_height="@dimen/tile_description_height"
    android:layout_marginTop="@dimen/margin_list_vertical"
    android:layout_marginBottom="@dimen/margin_list_vertical"
    android:background="@color/git"
    android:layout_toRightOf="@id/imageview_poi_tile_icon"/>

<!--This is the red map button on the right-->
<ImageView
    android:id="@id/imageview_poi_tile_map_button"
    android:background="@color/lr"
    android:src="@drawable/map"
    android:scaleType="fitCenter"
    android:padding="@dimen/image_button_padding"
    android:layout_width="@dimen/button_size"
    android:layout_height="match_parent"
    android:layout_alignParentRight="true"/>

<!--This is the marker Icon on the left-->
<ImageView
        android:id="@+id/imageview_poi_tile_icon"
        android:src="@drawable/poidefaultgit"
        android:scaleType="fitStart"
        android:padding="@dimen/image_button_padding"
        android:background="@color/ca"
        android:layout_width="@dimen/button_size"
        android:layout_height="@dimen/tile_description_height"
        android:layout_margin="0dp"/>

<!--This is the bold title text, eg. BARONS-->
<TextView
        android:id="@+id/textview_poi_tile_type"
        android:background="@color/ca"
        android:paddingLeft="@dimen/padding_list"
        android:layout_margin="0dp"
        android:gravity="left|top"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textStyle="bold"
        android:text="Poi Type"
        android:ellipsize="end"
        android:maxLines="1"
        android:textColor="@color/git"
        android:layout_width="match_parent"
        android:layout_height="@dimen/tile_title_height"
        android:layout_toRightOf="@id/delimiter_poi_tile"
        android:layout_toLeftOf="@+id/textview_poi_tile_distance"/>

<!--This is the address that is shown, eg 3 ADDERLEY ST, CAPE TOWN,-->
<TextView
        android:id="@+id/textview_poi_tile_description"
        android:background="@color/ca"
        android:paddingLeft="@dimen/padding_list"
        android:layout_margin="0dp"
        android:gravity="left|top"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="Address"
        android:ellipsize="end"
        android:maxLines="1"
        android:textColor="@color/git"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/textview_poi_tile_type"
        android:layout_toRightOf="@id/delimiter_poi_tile"
        android:layout_toLeftOf="@id/imageview_poi_tile_map_button"/>

<!--This will display a string when the gps is on, not shown in image as gps was off in screenshot-->
<TextView
        android:id="@id/textview_poi_tile_distance"
        android:background="@color/ca"
        android:textColor="@color/lr"
        android:text=""
        android:paddingRight="@dimen/padding_list"
        android:layout_margin="0dp"
        android:gravity="left|top"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/imageview_poi_tile_map_button"/>

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        TextView description;
        TextView type;
        TextView distance;
        ImageView imageView;
        ImageView mapIcon;
        ImageView clickableArea;

        if(convertView == null)
        {
            convertView = LayoutInflater.from(context).inflate(R.layout.listitem_poi, parent, false);

            description = (TextView) convertView.findViewById(R.id.textview_poi_tile_description);
            type = (TextView) convertView.findViewById(R.id.textview_poi_tile_type);
            distance = (TextView) convertView.findViewById(R.id.textview_poi_tile_distance);
            imageView = (ImageView) convertView.findViewById(R.id.imageview_poi_tile_icon);
            mapIcon = (ImageView) convertView.findViewById(R.id.imageview_poi_tile_map_button);
            clickableArea = (ImageView) convertView.findViewById(R.id.imageview_poi_tile_detail_button_detail);

            convertView.setTag(new ViewHolder(description, type, distance, imageView, mapIcon, clickableArea));
        }
        else
        {
            ViewHolder viewHolder = (ViewHolder) convertView.getTag();

            description = viewHolder.description;
            type = viewHolder.type;
            distance = viewHolder.distance;
            imageView = viewHolder.imageView;
            mapIcon = viewHolder.mapIcon;
            clickableArea = viewHolder.clickableArea;
        }

        final int finalIndex = position;
        final PointOfInterest poi = getItem(position);

        description.setText(poi.getDescription());
        type.setText(poi.getName());

        imageView.setImageResource(R.drawable.poidefaultgit);

        distance.setText(poi.getDistance()); 

        return convertView;
    }
hendrikdelarey
  • 452
  • 3
  • 12

3 Answers3

2

I think there are several things that are causing this. From experience, I've noticed RelativeLayout will sometimes not appropriately size it's children based on available space. It'll sooner let something get clipped if one of the sides of a child is not properly bounded somewhere. Also, I think some of the sizes for the TextViews just aren't enough to display the text. I did the following off the top of my head here so it may need some tweaking, however it should paint the picture of the layout to try. Unfortunately its not as flat as your current XML but it should hopefully fix your problem. Sorry not at a computer to test this currently.

<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <!--This is the marker Icon on the left-->
    <!--Use margin if you need more space to divider-->
    <ImageView
        android:id="@+id/imageview_poi_tile_icon"
        android:src="@drawable/poidefaultgit"
        android:scaleType="fitStart"
        android:padding="@dimen/image_button_padding"
        android:background="@color/ca"
        android:layout_width="@dimen/button_size"
        android:layout_height="match_parent"/>

    <!--This is the Grey vertical line next to the icon on the left-->
    <!--Use margin to determine how close the line is to the top/bottom of item-->
    <ImageView
        android:id="@+id/delimiter_poi_tile"
        android:layout_width="@dimen/delimiter_size"
        android:layout_height="match_parent"
        android:layout_marginTop="@dimen/margin_list_vertical"
        android:layout_marginBottom="@dimen/margin_list_vertical"
        android:src="@color/git"
        android:background="@color/ca"/>

    <RelativeLayout
        android:gravity="center_vertical"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:background="@color/ca">

        <!--This is the bold title text, eg. BARONS-->
        <TextView
            android:id="@+id/textview_poi_tile_type"
            android:paddingLeft="@dimen/padding_list"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textStyle="bold"
            android:text="Poi Type"
            android:ellipsize="end"
            android:maxLines="1"
            android:textColor="@color/git"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

        <!--This is the address that is shown, eg 3 ADDERLEY ST, CAPE TOWN,-->
        <TextView
            android:id="@+id/textview_poi_tile_description"
            android:paddingLeft="@dimen/padding_list"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:text="Address"
            android:ellipsize="end"
            android:maxLines="1"
            android:textColor="@color/git"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/textview_poi_tile_type"/>

        <!--This will display a string when the gps is on, not shown in image as gps was off in screenshot-->
        <TextView
            android:id="@id/textview_poi_tile_distance"
            android:textColor="@color/lr"
            android:text=""
            android:paddingRight="@dimen/padding_list"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/textview_poi_tile_type"/>
    </RelativeLayout>

    <!--This is the red map button on the right-->
    <ImageButton
        android:id="@id/imageview_poi_tile_map_button"
        android:background="@color/lr"
        android:src="@drawable/map"
        android:scaleType="fitCenter"
        android:padding="@dimen/image_button_padding"
        android:layout_width="@dimen/button_size"
        android:layout_height="match_parent"/>
</LinearLayout>

The idea here is to have the entire item in a LinearLayout that wraps to the size of the contents. Rely on it for getting everything horizontally in place. Then only wrap the TextViews in a Relativelayout. Just have the TextViews align beneath and to the side of each other. Have the RelativeLayout worry about actually centering them accordingly. It's weighted to ensure it stretches to fill any remaining space horizontally.

Also, your map button can be an ImageButton. You don't need a view solely to take the item click event. The root layout itself can do it as is. You probably ran into an issue with this setup. Check out this post which tells you how to properly get a row to click when an ImageButton is embedded.

Community
  • 1
  • 1
Ifrit
  • 6,791
  • 8
  • 50
  • 79
0

Try inflating a new view every time instead of re-using them. I know it isn't the best thing to do, but at some point i had similar problems and this was the only thing that worked.

gtsouk
  • 5,208
  • 1
  • 28
  • 35
0

Thanks for the help. I managed to clean up the layout file a lot.

The reason that the UI glitch was happening is due to the wrong style file being loaded. It only happened when I loaded another element before that used that style. To solve it I created a new style specifically for the listviews and assigned it to the listview elements.

hendrikdelarey
  • 452
  • 3
  • 12