2012-01-27 3 views
13

J'essaie d'obtenir la vue suivante: Description sur le site gauche et la valeur sur la droite. .: par exemple Android HorizontalScrollView avec droit layout_gravity fonctionne mal

enter image description here


Le problème est que le texte peut être long pour que je l'envelopper dans HorizontalScrollView. J'utilise xml suivant:

<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> 

Et voici le problème. Après scroling à gauche plus coin, je me suis vue (de début de texte manquantes):

enter image description here


Après scroling à droite coin le plus je me suis vue (espace d'addition après le texte):

enter image description here


Si je change le TextView android: layout_gravity à "gauche" tout fonctionne comme prévu. Après scroling à gauche plus coin, je me suis vue:

enter image description here


Après scroling à droite coin le plus je me suis vue:

enter image description here


est-il un moyen de le faire fonctionner correctement et aligner le texte sur le bon site quand il est court?

Répondre

1

N'utilisez pas de gravité de mise en page pour TextView, cela fonctionnera comme prévu.

Comme vous l'avez dit, le problème est là, il se comporte mal avec la gravité juste.

+0

Mais je veux que le texte soit à droite, si elle est courte (voir première image). Si j'enlève la gravité - le comportement est exactement comme avec la gravitation réglée à gauche. La question est: comment aligner ou défiler à droite, en fonction de la longueur du texte. – Remi

1

Je sais que cela a été inactif pendant un an, mais c'est toujours un problème en 2013. Créez une nouvelle classe qui étend HorizontalScrollView et copier/coller le code ci-dessous.

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

Je sais que ça fait un certain temps, mais voici une solution de contournement (testé):

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

}

Questions connexes