2
votes

How can I set the layout gravity for AbsListView.LayoutParams?

I am using this in a custom array adapter where I need to set the layout gravity based on a variable. My list child contains a linear layout root but in the adapter, I cannot set the LinearLayout params as i get the error that LinearLayout.LayoutParams cannot be cast to AbsListView.Layout params.

So, I tried to set the layout_gravity for an AbsListView, but it has no option for a gravity.

How can I set the layout_gravity programatically in this case?

EDIT: (Added source code)

The Listview Parent

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/messaging_background"
    android:orientation="vertical"
    android:padding="2dp" >

    <ListView
        android:id="@+id/messageThread"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/list_separator"
        android:layout_alignParentTop="true"
        android:layout_marginTop="5dp"
        android:cacheColorHint="#00000000"
        android:divider="@null"
        android:dividerHeight="2dp"
        android:fastScrollEnabled="false"
        android:listSelector="#00000000"
        android:transcriptMode="disabled" />

    <View
        android:id="@+id/list_separator"
        android:layout_width="match_parent"
        android:layout_height="1.0dip"
        android:layout_above="@+id/footer"
        android:background="@android:color/white" />

    <LinearLayout
        android:id="@+id/footer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >

        <ImageButton
            android:id="@+id/filter"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="0.1"
            android:background="@null"
            android:contentDescription="@string/message_filter_button"
            android:scaleType="fitCenter"
            android:src="@drawable/filter" />

        <EditText
            android:id="@+id/send_message_text"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="0.8"
            android:imeOptions="actionSend"
            android:inputType="textMultiLine"
            android:maxLines="6"
            android:scrollbarAlwaysDrawVerticalTrack="true"
            android:scrollbarDefaultDelayBeforeFade="200"
            android:scrollbarFadeDuration="300"
            android:scrollbarStyle="outsideOverlay"
            android:scrollbars="vertical" />

        <ImageButton
            android:id="@+id/send"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="0.1"
            android:background="@null"
            android:contentDescription="@string/send_message_button"
            android:scaleType="fitCenter"
            android:src="@drawable/send_btn" />
    </LinearLayout>

</RelativeLayout>

The Listview Child

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:background="@drawable/incoming"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/messaging_bubble_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:fontFamily="sans-serif-light"
        android:maxWidth="200dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textIsSelectable="true" />

    <TextView
        android:id="@+id/messaging_bubble_time"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:fontFamily="sans-serif-light"
        android:gravity="center"
        android:paddingRight="5dp"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textIsSelectable="false" />

    <ImageView
        android:id="@+id/messaging_bubble_megaphone"
        android:layout_width="20dp"
        android:layout_height="match_parent"
        android:contentDescription="@string/message_child_megaphone"
        android:src="@drawable/megaphone"
        android:visibility="gone" />

</LinearLayout>

What should I call in the getView of my adapter to push the child to the right according to a variable in the adapter?

EDIT 2:

A possible solution: Wrap the whole child under another element under the root and then you can set gravity instead of layout gravity which can be easily done using the setGravity() method.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/messaging_bubble_wrapper"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:background="@drawable/incoming"
        android:orientation="vertical"
        tools:ignore="UselessParent" >

The second linear layout is useless but having it gets the job done!

4
You could wrap the existent row layout in another layout(FrameLayout for example) and then simply set the gravity on the Linearlayout from that FrameLayout. However if you're trying to make some sort of messaging list like rows I recommend that you create an adapter with two types of rows.user
This is exactly what I ended up doing. Seems hacky but its the easiest solution i could find.nknj
It's not that hacky because the LayoutParams for AdapterViews don't allow gravity(as the children are managed by the widget itself).user
Ok, that makes sense. The "useless parent" warning from eclipse was making me feel like it was a little hacky. haha. Anyways, thank you.nknj
It's just a warning as Eclipse doesn't know/see that you'll be using that layout in code. You could improve that by using a RelativeLayout instead of the parent LinearLayout for your row layout and move the children accordingly.user

4 Answers

5
votes

To change the gravity you could wrap the existent row layout in another layout(FrameLayout for example) and then simply set the gravity on the LinearLayout from that extra layout(which now can be moved inside the parent).

To avoid adding an extra level in the layout you could keep the current row layout and replace the root LinearLayout with a RelativeLayout and change the position of the views inside it according to your desired gravity.

2
votes

I solved this problem by creating another "useless view (in eclipse's words)" under my root element.

I set the width of the parent to match_parent and then changed the gravity to move the "useless view" left or right. The setGravity(Gravity.LEFT) method is allowed on the AbsListView.

1
votes

I think you need to get rid of the ListView. Replace the ListView with a FrameLayout and use the layoutinflater to add the "listview" child into the FrameLayout. When using the layoutinflater set the FrameLayout.LayoutParams with the gravity property assigned to the root of the child (LinearLayout). Good luck.

1
votes

You can set the gravity of the child's content with setGravity():

View child;
boolean left;

child.setGravity(left ? Gravity.LEFT : Gravity.RIGHT);

And the child should be changed to android:layout_width="match_parent".