【问题标题】:Android HorizontalScrollView with right layout_gravity working wrong具有正确 layout_gravity 的 Android Horizo​​ntalScrollView 工作错误
【发布时间】:2012-02-20 08:31:15
【问题描述】:

我正在尝试获取以下视图:左侧站点的描述和右侧的值。例如:


问题是文本可能很长,所以我将其包装在 Horizo​​ntalScrollView 中。我正在使用以下 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>

这就是问题所在。滚动到最左边的角落后,我看到了(缺少文本开头):


滚动到最右边的角落后,我看到了(文本后添加空格):


如果我将 TextView android:layout_gravity 更改为“左”,一切都会按预期工作。滚动到最左边的角落后,我看到了:


滚动到最右边的角落后,我看到了:


这是一种让它正常工作并在文本较短时将文本与正确站点对齐的方法吗?

【问题讨论】:

    标签: android scroll textview


    【解决方案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 年仍然是一个问题。创建一个扩展 Horizo​​ntalScrollView 的新类并复制/粘贴下面的代码。

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

      【讨论】:

        【解决方案4】:

        添加到您的子布局中

        android:layout_gravity="right"
        

        这应该有效(对我来说是这样) 希望对你有帮助

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多