2011-03-29 72 views
12

我想让textviews浮动到左边(像css浮动)。我有这么多textviews的原因是我希望我的应用程序中的每个单词都是可点击的。所以,我想这样的结果: enter image description hereAndroid:我如何让文字视图浮动到左侧?

目前,我有以下XML代码:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" android:orientation="horizontal" android:baselineAligned="false"> 
    <TextView android:text="@string/nicholasStr" android:layout_width="wrap_content" android:textSize="18sp" android:textStyle="bold" android:layout_height="wrap_content" android:id="@+id/nicholas" ></TextView> 
    <TextView android:text="@string/wasStr" android:layout_width="wrap_content" android:textSize="18sp" android:textStyle="bold" android:id="@+id/was" android:layout_height="wrap_content" ></TextView> 
    <TextView android:layout_width="wrap_content" android:textSize="18sp" android:textStyle="bold" android:id="@+id/dots" android:layout_height="wrap_content" android:text="@string/dots"></TextView> 
    <TextView android:layout_width="wrap_content" android:textSize="18sp" android:textStyle="bold" android:layout_height="wrap_content" android:text="@string/older" android:id="@+id/older"></TextView> 
    <TextView android:layout_width="wrap_content" android:textSize="18sp" android:textStyle="bold" android:layout_height="wrap_content" android:text="@string/older" android:id="@+id/older"></TextView> 
    <TextView android:layout_width="wrap_content" android:textSize="18sp" android:textStyle="bold" android:layout_height="wrap_content" android:text="@string/older" android:id="@+id/older"></TextView> 
    <TextView android:text="@string/older" android:layout_width="wrap_content" android:textSize="18sp" android:textStyle="bold" android:layout_height="wrap_content" android:id="@+id/older"></TextView> 
</LinearLayout> 

但结果是这样的:

enter image description here

我是新来的android dev,非常感谢。 :)

+0

尝试使用'机器人:方向=“垂直“'。 – 2011-03-29 03:10:50

+0

尝试使用'RelativeLayout'并检查这篇文章[link] http://developer.android.com/resources/articles/layout-tricks-efficiency.html – ASMaitre 2011-03-29 03:32:53

+1

如果您在java中而不是使用xml动态创建它们。你可以检查最后一个的右边缘,看看它离屏幕边缘有多远,所以知道何时需要跳到下一行。 – FoamyGuy 2011-03-29 03:35:58

回答

19

你真正需要的是包装整个视图的行布局。不幸的是,Android没有一个。幸运的是,虽然,我喜欢! ;)

这是一个自定义类,但你可以在XML就好了,只要用它作为你完全限定它,包括在水库下面attrs.xml文件/值

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="RowLayout"> 
     <attr name="android:verticalSpacing" /> 
     <attr name="android:horizontalSpacing" /> 
    </declare-styleable> 
</resources> 

这里来源:

package com.example.widget; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Iterator; 
import java.util.List; 

import android.content.Context; 
import android.content.res.TypedArray; 
import android.util.AttributeSet; 
import android.view.View; 
import android.view.ViewGroup; 

import com.example.widget.R; 

public class RowLayout extends ViewGroup { 
    public static final int DEFAULT_HORIZONTAL_SPACING = 5; 
    public static final int DEFAULT_VERTICAL_SPACING = 5; 
    private final int horizontalSpacing; 
    private final int verticalSpacing; 
    private List<RowMeasurement> currentRows = Collections.emptyList(); 

    public RowLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.RowLayout); 
     horizontalSpacing = styledAttributes.getDimensionPixelSize(R.styleable.RowLayout_android_horizontalSpacing, 
       DEFAULT_HORIZONTAL_SPACING); 
     verticalSpacing = styledAttributes.getDimensionPixelSize(R.styleable.RowLayout_android_verticalSpacing, 
       DEFAULT_VERTICAL_SPACING); 
     styledAttributes.recycle(); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
     final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
     final int maxInternalWidth = MeasureSpec.getSize(widthMeasureSpec) - getHorizontalPadding(); 
     final int maxInternalHeight = MeasureSpec.getSize(heightMeasureSpec) - getVerticalPadding(); 
     List<RowMeasurement> rows = new ArrayList<RowMeasurement>(); 
     RowMeasurement currentRow = new RowMeasurement(maxInternalWidth, widthMode); 
     rows.add(currentRow); 
     for (View child : getLayoutChildren()) { 
      LayoutParams childLayoutParams = child.getLayoutParams(); 
      int childWidthSpec = createChildMeasureSpec(childLayoutParams.width, maxInternalWidth, widthMode); 
      int childHeightSpec = createChildMeasureSpec(childLayoutParams.height, maxInternalHeight, heightMode); 
      child.measure(childWidthSpec, childHeightSpec); 
      int childWidth = child.getMeasuredWidth(); 
      int childHeight = child.getMeasuredHeight(); 
      if (currentRow.wouldExceedMax(childWidth)) { 
       currentRow = new RowMeasurement(maxInternalWidth, widthMode); 
       rows.add(currentRow); 
      } 
      currentRow.addChildDimensions(childWidth, childHeight); 
     } 

     int longestRowWidth = 0; 
     int totalRowHeight = 0; 
     for (int index = 0; index < rows.size(); index++) { 
      RowMeasurement row = rows.get(index); 
      totalRowHeight += row.getHeight(); 
      if (index < rows.size() - 1) { 
       totalRowHeight += verticalSpacing; 
      } 
      longestRowWidth = Math.max(longestRowWidth, row.getWidth()); 
     } 
     setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? MeasureSpec.getSize(widthMeasureSpec) : longestRowWidth 
       + getHorizontalPadding(), heightMode == MeasureSpec.EXACTLY ? MeasureSpec.getSize(heightMeasureSpec) 
       : totalRowHeight + getVerticalPadding()); 
     currentRows = Collections.unmodifiableList(rows); 
    } 

    private int createChildMeasureSpec(int childLayoutParam, int max, int parentMode) { 
     int spec; 
     if (childLayoutParam == LayoutParams.FILL_PARENT) { 
      spec = MeasureSpec.makeMeasureSpec(max, MeasureSpec.EXACTLY); 
     } else if (childLayoutParam == LayoutParams.WRAP_CONTENT) { 
      spec = MeasureSpec.makeMeasureSpec(max, parentMode == MeasureSpec.UNSPECIFIED ? MeasureSpec.UNSPECIFIED 
        : MeasureSpec.AT_MOST); 
     } else { 
      spec = MeasureSpec.makeMeasureSpec(childLayoutParam, MeasureSpec.EXACTLY); 
     } 
     return spec; 
    } 

    @Override 
    protected void onLayout(boolean changed, int leftPosition, int topPosition, int rightPosition, int bottomPosition) { 
     final int widthOffset = getMeasuredWidth() - getPaddingRight(); 
     int x = getPaddingLeft(); 
     int y = getPaddingTop(); 

     Iterator<RowMeasurement> rowIterator = currentRows.iterator(); 
     RowMeasurement currentRow = rowIterator.next(); 
     for (View child : getLayoutChildren()) { 
      final int childWidth = child.getMeasuredWidth(); 
      final int childHeight = child.getMeasuredHeight(); 
      if (x + childWidth > widthOffset) { 
       x = getPaddingLeft(); 
       y += currentRow.height + verticalSpacing; 
       if (rowIterator.hasNext()) { 
        currentRow = rowIterator.next(); 
       } 
      } 
      child.layout(x, y, x + childWidth, y + childHeight); 
      x += childWidth + horizontalSpacing; 
     } 
    } 

    private List<View> getLayoutChildren() { 
     List<View> children = new ArrayList<View>(); 
     for (int index = 0; index < getChildCount(); index++) { 
      View child = getChildAt(index); 
      if (child.getVisibility() != View.GONE) { 
       children.add(child); 
      } 
     } 
     return children; 
    } 

    protected int getVerticalPadding() { 
     return getPaddingTop() + getPaddingBottom(); 
    } 

    protected int getHorizontalPadding() { 
     return getPaddingLeft() + getPaddingRight(); 
    } 

    private final class RowMeasurement { 
     private final int maxWidth; 
     private final int widthMode; 
     private int width; 
     private int height; 

     public RowMeasurement(int maxWidth, int widthMode) { 
      this.maxWidth = maxWidth; 
      this.widthMode = widthMode; 
     } 

     public int getHeight() { 
      return height; 
     } 

     public int getWidth() { 
      return width; 
     } 

     public boolean wouldExceedMax(int childWidth) { 
      return widthMode == MeasureSpec.UNSPECIFIED ? false : getNewWidth(childWidth) > maxWidth; 
     } 

     public void addChildDimensions(int childWidth, int childHeight) { 
      width = getNewWidth(childWidth); 
      height = Math.max(height, childHeight); 
     } 

     private int getNewWidth(int childWidth) { 
      return width == 0 ? childWidth : width + horizontalSpacing + childWidth; 
     } 
    } 
} 
+0

会很高兴让像我这样的新手知道他们需要以下行: xmlns:app =“http://schemas.android.com/apk/res-auto” 在根布局。即 2014-04-27 09:29:10

+0

很好的答案。奇迹般有效。如果你能把它放在Github上,也许只有一个小文档,那将是非常棒的。让我知道如果我可以帮助:) – 2017-05-30 07:44:50

0

您可以使用orientation = vertical的Relative布局轻松实现。

例如:在activity_main.xml中的文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" > 

<Button 
    android:id="@+id/btnButton1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Button 1"/> 

<Button 
    android:id="@+id/btnButton2" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Button 2" 
    android:layout_toRightOf="@+id/btnButton1"/> 

<TextView 
    android:id="@+id/textView1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_below="@+id/btnButton3" 
    android:layout_marginTop="94dp" 
    android:text="User :" 
    android:textAppearance="?android:attr/textAppearanceLarge" /> 
    ....... 

</RelativeLayout> 
0

我发现了一个非常简单的解决方案来创建一个菜单选项行:

public class OptionMenu extends LinearLayout { 
private int widthConsumed = 0; 
private LinearLayout currentRow; 

interface OptionRunnable { 
    void onOptionSelected(int option); 
} 

public OptionMenu(Context context) { 
    super(context); 
    setOrientation(VERTICAL); 
} 

public void setOptions(List<Integer> options, OptionRunnable runnable) { 
    getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
     @Override 
     public boolean onPreDraw() { 
      getViewTreeObserver().removeOnPreDrawListener(this); 

      Stream.of(options).forEach(option -> { 
       TextView text = (TextView) LayoutInflater.from(getContext()).inflate(R.layout.incl_textviewer_option_button, OptionMenu.this, false); 
       text.setText(option); 
       text.setTag(option); 
       text.setOnClickListener(v -> runnable.onOptionSelected((Integer) v.getTag())); 

       text.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); 
       getCurrentRow(text.getMeasuredWidth()).addView(text); 
      }); 
      return true; 
     } 
    }); 
} 

private LinearLayout getCurrentRow(int width) { 
    if(currentRow == null) { 
     currentRow = new LinearLayout(getContext()); 
     currentRow.setOrientation(HORIZONTAL); 
     addView(currentRow); 
    } 

    widthConsumed += width; 

    if(widthConsumed < getWidth()) 
     return currentRow; 

    LinearLayout newRow = new LinearLayout(getContext()); 
    newRow.setOrientation(HORIZONTAL); 
    currentRow = newRow; 
    widthConsumed = width; 
    addView(newRow); 

    return newRow; 
} 
} 
相关问题