Android HorizontalScrollView с правильным layout_gravity работает неправильно - PullRequest
14 голосов
/ 27 января 2012

Я пытаюсь получить следующий вид: описание на левом сайте и значение справа.Например:

enter image description here


Проблема в том, что текст может быть длинным, поэтому я обертываю его в HorizontalScrollView.Я использую следующий 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>

И вот проблема.После прокрутки в самый левый угол я получил вид ( отсутствует начало текста ):

enter image description here


После прокрутки в самый правый угол я получил вид ( добавление пробела после текста ):

enter image description here


Если я изменю TextView android: layout_gravity на «left», все будет работать как положено.После прокрутки в самый левый угол я получил вид:

enter image description here


После прокрутки в самый правый угол я получил вид:

enter image description here


Это способ заставить его работать правильно и выровнять текст по нужному сайту, когда он короткий?

Ответы [ 4 ]

2 голосов
/ 17 ноября 2013

Я знаю, что это было давно, но вот обходной путь (проверено):

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);
}

}

1 голос
/ 04 февраля 2013

Я знаю, что это было неактивно в течение года, но это все еще проблема в 2013 году. Создайте новый класс, расширяющий HorizontalScrollView, и скопируйте / вставьте приведенный ниже код.

@Override
public boolean onTouchEvent(MotionEvent ev) {
    autoScrolling = false;
    return super.onTouchEvent(ev);
}

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

private boolean gravityRight = false;
private boolean autoScrolling = false;

@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.
    if(getChildCount() == 0) return super.onLayout(changed, left, top, right, bottom);
    int childWidth = getChildAt(0).getWidth();
    super.onLayout(changed, left, top, right, bottom);
    int delta = getChildAt(0).getWidth() - childWidth;
    AdvancedDisplay view = getView();
    ScrollableDisplay.LayoutParams p = (LayoutParams) view.getLayoutParams();
    int horizontalGravity = p.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
    int verticalGravity = p.gravity & Gravity.VERTICAL_GRAVITY_MASK;
    if(horizontalGravity == Gravity.RIGHT) {
        if(getScrollRange() > 0) {
            gravityRight = true;
            p.gravity = Gravity.LEFT | verticalGravity;
            view.setLayoutParams(p);
            super.onLayout(changed, left, top, right, bottom);
        }
    }
    else if(gravityRight) {
        if(getScrollRange() == 0) {
            gravityRight = false;
            p.gravity = Gravity.RIGHT | verticalGravity;
            view.setLayoutParams(p);
            super.onLayout(changed, left, top, right, bottom);
        }
    }
    if(gravityRight && delta > 0) {
        autoScrolling = false;
        scrollBy(delta, 0);
        autoScrolling = true;
    }
}

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

@Override
public void scrollTo(int x, int y) {
    if(autoScrolling) return;
    super.scrollTo(x, y);
}
1 голос
/ 31 января 2012

Не используйте макет гравитации для TextView, он будет работать только так, как вы ожидали.

Как вы сказали, проблема в том, что она ведет себя неправильно с правильной гравитацией.

0 голосов
/ 03 мая 2018

Добавьте в свой дочерний макет

android:layout_gravity="right"

Это должно работать (для меня это так) Надеюсь, это поможет

...