Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android HorizontalScrollView with right layout_gravity working wrong

I'm trying to get following view: Description on left site and value on the right. e.g.:

enter image description here


The problem is that the text can be long so I wrap it in HorizontalScrollView. I'm using following xml:

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_weight="1"
    android:orientation="horizontal"
    android:layout_height="wrap_content">
    <TextView
        android:layout_height="wrap_content"
        android:textColor="#000000"
        android:layout_width="110dp"
        android:text="Description:"/>
    <HorizontalScrollView
        android:layout_weight="1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:layout_height="wrap_content"
            android:textColor="#000000"
            android:layout_width="wrap_content"
            android:layout_gravity="right"
            android:text="Very1 very2 very3 very4 very5 very6 long text"/>
    </HorizontalScrollView>
</LinearLayout>

And here is the problem. After scroling to left most corner I got view (missing beginning of text):

enter image description here


After scroling to right most corner I got view (addition space after text):

enter image description here


If I change the TextView android:layout_gravity to "left" everything works as expected. After scroling to left most corner I got view:

enter image description here


After scroling to right most corner I got view:

enter image description here


Is it a way to make it working correctly and align text to right site when it is short?

like image 823
Remi Avatar asked Jan 27 '12 10:01

Remi


1 Answers

I know it's been a while but here is a workaround (tested):

public class RightAlignedHorizontalScrollView extends HorizontalScrollView {
private boolean mGravityRight = false;
private boolean mAutoScrolling = false;

public RightAlignedHorizontalScrollView(Context context) {
    super(context);
}

public RightAlignedHorizontalScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public RightAlignedHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public View getChildView() {
    return getChildAt(0);
}

private int getScrollRange() {
    int scrollRange = 0;
    if (getChildCount() > 0) {
        View child = getChildAt(0);
        scrollRange = Math.max(0, child.getWidth() - (getWidth() - getPaddingLeft() - getPaddingRight()));
    }
    return scrollRange;
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    // HorizontalScrollView is broken for Gravity.RIGHT. So we're fixing it.
    mAutoScrolling = false;
    int childWidth = getChildView().getWidth();
    super.onLayout(changed, left, top, right, bottom);
    int delta = getChildView().getWidth() - childWidth;
    View childView = getChildView();
    FrameLayout.LayoutParams p = (LayoutParams) childView.getLayoutParams();
    int horizontalGravity = p.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
    int verticalGravity = p.gravity & Gravity.VERTICAL_GRAVITY_MASK;
    if (horizontalGravity == Gravity.RIGHT) {
        if (getScrollRange() > 0) {
            mGravityRight = true;
            p.gravity = Gravity.LEFT | verticalGravity;
            childView.setLayoutParams(p);
            super.onLayout(changed, left, top, right, bottom);
        }
    } else if (mGravityRight) {
        if (getScrollRange() == 0) {
            mGravityRight = false;
            p.gravity = Gravity.RIGHT | verticalGravity;
            childView.setLayoutParams(p);
            super.onLayout(changed, left, top, right, bottom);
        }
    }
    if (mGravityRight && delta > 0) {
        scrollBy(delta, 0);
        mAutoScrolling = true;
    }
}

@Override
public void computeScroll() {
    if (mAutoScrolling) return;
    super.computeScroll();
}

@Override
public void scrollTo(int x, int y) {
    if (mAutoScrolling) return;
    super.scrollTo(x, y);
}

}

like image 66
hrules6872 Avatar answered Oct 21 '22 02:10

hrules6872