Sarah Sakamoto
Sarah Sakamoto

Reputation: 949

Android - How to show a vertical line on the background of a ListView (and according to row height)?

How to show a vertical line on the background, such as the one highlighted in blue on the image below?

enter image description here

In this example, I have a ListView with ImageView elements (and TextView, but it is not related to the line), and I want a vertical line on the background of these items to feel like they are "connected" to each one.

And also, note that the vertical line does not fill all the background.

The vertical line is on the left, and it is not equal for the all cases. Sometimes it fills all the row height (in most of ListView rows) and sometimes it just fills the half of row height (in the last item of the ListView and outside of the ListView, on the top, where we can see the big ImageView with the star icon).

Updated

I tried the suggestion proposed by Hellboy, and it almost work perfectly. I modified the proposed code for my case:

<RelativeLayout 
android:layout_width="40dp"
android:layout_height="match_parent"
android:gravity="center"
android:layout_marginLeft="15dp">

<View
    android:layout_width="4dp"
    android:layout_height="match_parent"
    android:background="#3399CC"
    android:gravity="center"
    android:layout_centerHorizontal="true"/>

<ImageView
    android:id="@+id/user_image"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp"
    android:gravity="center"
    android:background="@android:color/holo_blue_light" >
</ImageView> 
</RelativeLayout>

the RelativeLayout with the width="40dp" (the same as the original ImageView I was working with), height="match_parent (the same as he said), gravity="center" (to let them in the center of the row height) and layout_marginLeft="15dp" (to let a space to the left margin). In the ImageView, I added marginTop="10dp" and marginBottom="10dp", and with it, the blue vertical line appears. But I have other elements in the same row, so I have a parent layout (a linear layout). My parent layout is:

<?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:orientation="horizontal"
    android:gravity="center"
    android:id="@+id/linearlayoutservicerow">

So, this parent layout above, has the described RelativeLayout and other LinearLayout with the other row elements. But the code results in flattened images. Why does this happen?! It seems like the RelativeLayout consider its height as the ImageView height (40dp) and does consider its marginTop and marginBottom, and with this the image is flattened.

Waiting more answers to this problem. I'll try another alternatives.

Upvotes: 11

Views: 5580

Answers (4)

Sarah Sakamoto
Sarah Sakamoto

Reputation: 949

I got it.

I've persisted in trying to fix the problem of the Updated section of my question (based on the solution initially proposed by @Hellboy) and I got results! So, how I achieved an answer to my own question, I decided to put as an answer.

The first step was to configure the XML file such as the code below.

Part of the final XML corresponding to the row layout:

<?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:orientation="horizontal"
    android:gravity="center"
    android:id="@+id/linearlayoutservicerow">

    <RelativeLayout 
        android:layout_width="40dp"
        android:layout_height="match_parent"
        android:gravity="center"
        android:layout_marginLeft="15dp">

        <View
            android:layout_width="4dp"
            android:id="@+id/verticallineview"
            android:layout_height="match_parent"
            android:background="#3399CC"
            android:gravity="center"
            android:layout_centerHorizontal="true"/>

        <RelativeLayout 
        android:layout_width="40dp"
        android:layout_height="match_parent"
        android:gravity="center"
        android:paddingBottom="10dp"
        android:paddingTop="10dp">

            <ImageView
                android:id="@+id/user_image"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:gravity="center"
                android:background="@android:color/holo_blue_light" >
            </ImageView>

        </RelativeLayout>
    </RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layoutotherrowelements">
    </LinearLayout>

</LinearLayout>

Explaining the XML:

Here we have the parent layout (linearlayoutservicerow) and inside it: a RelativeLayout (proposed by @HellBoym, with the structured discussed in the final of my question) and the LinearLayout to other elements of the row (layoutotherrowelements). Summarizing... What I modified?

The initial code resulted in flattened images because the RelativeLayout (parent) did not consider the ImageView marginTop and marginBottom, so the image was flattened vertically. (And if we let without margin, the RelativeLayout would mantain the same size and the vertical line would not appear on the top and on the bottom of image.) We must have a space between the ImageView and the RelativeLayout initially proposed, in order to show the line, but if it does not recognize the margin, how to create this space?

I just "encapsulated" the ImageView in another RelativeLayout (inside that parent RelativeLayout), and changed the margin parameters of the ImageView to padding parameters of this capsule RelativeLayout.

The problem of the last row

It results in the layout with a line background, but we still have the problem of the last row. In fact, this row is different, and in this case, it must have its height modified to not have the same parent's height. I decided to put at least, the ImageView's height and it worked! Remember to convert the value in dp to pixel, because the function getLayoutParams has all parameters expressed in pixels.

So, in the Adapter, we put the following code:

if(position==(getCount()-1)){
View my_line = (View)
    row.findViewById(R.id.verticallineview);
    //40dp, this is the ImageView height
    int dpsize = 40;
    //convert the height in dp unit to pixel (because the parameter is in px)
    int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpsize, context.getResources().getDisplayMetrics()); 
    my_line.getLayoutParams().height = px;
}

And that is it!!!

It is worth mentioning that @dinesh sharma proposed other interesting alternative using 9-patch, that I will try later.

I did not want to use image as background (that is why I started asking about drawable), because my final goal was to improve this solution to make all dynamic (including the vertical line color), and I believe with image I could not achieve it. But in my original question I did not mention that, so if I have success with this other approach, I will accept it as correct answer.

Thanks for all your help! In my current solution I used the @Hellboy's clue of using a RelativeLayout and a View, and the @dinesh sharma's clue to verify if it is the last row of the ListView. I hope this answer and the others helps more people with similar problems.

Upvotes: 4

dinesh sharma
dinesh sharma

Reputation: 3332

Now verified answer

your image in item layout:

<RelativeLayout
    android:id="@+id/rl"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:background="@drawable/m"
    android:paddingBottom="10dp"
    android:paddingTop="10dp" >

    <ImageView
        android:id="@+id/grid_item_image"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerInParent="true"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>

three bg nine patch images for drawable top blank fill content bottom blank

Handling in Adapter:

    if(position==0)
        holder.rl.setBackgroundResource(R.drawable.b);
    if(position==(getCount()-1))
        holder.rl.setBackgroundResource(R.drawable.t);

Finaly got output:

enter image description here enter image description here

Upvotes: 1

Hellboy
Hellboy

Reputation: 1062

You can replace your ImageView with something like this:

<RelativeLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:layout_width="4dp"
        android:layout_height="match_parent"
        android:background="@color/navy_blue"
        android:layout_centerHorizontal="true"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/image"/>
</RelativeLayout>

and of course in your first and last element you need to manipulate the height of the View and align it to Top or Bottom

Upvotes: 5

dinesh sharma
dinesh sharma

Reputation: 3332

You can use transparent 9-patch image as a background for you list view.

For creating nine-patch image please follow this: http://developer.android.com/tools/help/draw9patch.html

Upvotes: 3

Related Questions