Подтвердить что ты не робот

Android HorizontalScrollView с правильным layout_gravity работает неправильно

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

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


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

enter image description here


После прокрутки к самому большому углу я получил представление:

enter image description here


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

4b9b3361

Ответ 1

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

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

}

Ответ 2

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

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

Ответ 3

Я знаю, что это неактивно в течение года, но это все еще проблема в 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);
}