2010-10-29 86 views
139

View's have a minHeight但不知何故,缺乏一個maxHeightAndroid:爲什麼沒有maxHeight的視圖?

我想要實現的是有一些項目(視圖)填補了ScrollView。有1..3個項目時,我想直接顯示它們。意思是ScrollView的高度爲1,2或3個項目。

當有4個或更多項目時,我想ScrollView停止擴展(因此maxHeight)並開始提供滾動。

但是,很遺憾沒有辦法設置maxHeight。所以我可能必須以編程方式將ScrollView高度設置爲WRAP_CONTENT,當有1..3個項目時,並且在有4個或更多項目時將高度設置爲3*sizeOf(View)

任何人都可以解釋爲什麼沒有maxHeight提供,當已經有minHeight

(BTW:一些看法,像ImageViewmaxHeight實現)。

+0

我已經發布了其他線程的解決方案: http://stackoverflow.com/questions/18425758/how-to-set-a-maximum-height-with-wrap-content-in-android/26758657#26758657 – JMPergar 2014-11-05 13:45:07

+2

我爲此創建了一個解決方案http://chintanrathod.com/maxheightscrollview-in-android-using-android-studio/ – 2015-04-28 06:20:31

+0

Google刪除maxHeight令人討厭且不方便。看看你現在要做的所有事情,以獲得相同的結果。 – 2017-02-28 13:46:13

回答

1

您是否嘗試過使用layout_weight value?如果將其設置爲大於0的值,則會將該視圖拉伸到剩餘可用空間中。

如果您有多個需要拉伸的視圖,則該值將成爲它們之間的權重。

所以,如果你有兩個視圖都設置爲1的layout_weight值,那麼它們都會伸展以填充空間,但它們都會伸展到等量的空間。如果將其中一個值設置爲2,那麼它將拉伸兩倍於另一個視圖的值。

Some more info here listed under Linear Layout.

+1

權重的問題是它們是相對的。不同的屏幕尺寸,不同的結果,例如與一個800像素的屏幕我可以設置一個重量到一定的值,以便一個特定的區域結束與所需的200像素。但是,對於850像素的屏幕,特定區域最終會大於200像素,但封閉的元素仍然只有200像素。這就是爲什麼我更喜歡有一個'maxHeight',我可以設置一個特定的dip值。 (我終於以編程方式結束了計算和設置高度) – znq 2010-11-03 11:20:32

0

我覺得你可以在運行時設置heiht 1項只是scrollView.setHeight(200px),2項scrollView.setheight(400px) 3個或更多scrollView.setHeight(600px)

+8

您不想在'px'中設置維度。很可能你沒有在多個設備上得到你想要的結果。 http://developer.android.com/guide/topics/resources/more-resources.html#Dimension – 2012-03-05 10:48:51

+0

@HerndDerBeld這就是它如何在代碼中工作。如果你願意,你也可以轉換從DP到像素很容易:浮動像素= TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DP,context.getResources() \t \t \t \t .getDisplayMetrics()); – 2014-04-10 07:33:48

1

我們知道運行Android可以有不同屏幕尺寸的設備。正如我們進一步知道視圖應該動態調整,併成爲適當的空間。

如果設置最大高度,則可能會強制視圖不能獲得足夠的空間或佔用較小的空間。我知道有時似乎實際上是設定最大高度。但是,如果分辨率會發生劇烈變化,而且會發生變化,那麼具有最大高度的視圖看起來不合適。

我認爲沒有正確的方法來準確地做你想要的佈局。我會建議你使用佈局管理器和相關機制來思考你的佈局。我不知道你想要達到什麼目標,但對我來說聽起來有點奇怪,一個列表應該只顯示三個項目,然後用戶必須滾動。

btw。 minHeight不能保證(也許不應該存在)。它可以有一些好處,強制項目可見,而其他相關項目變得更小。

+6

這是錯誤的。通過這個邏輯,你也不會說android:layout_width =「500dp」。 – 2013-05-14 20:09:55

+0

我不明白你的邏輯解釋應該是什麼錯。如果您設置了layout_width(有時可以),但並不能保證你能得到。 500dp可能在適當的設備上查看,而在另一個設備上則不適用。佈局經理ftw!也許你可以解釋更多的bcs的投票bothers :) – 2013-05-15 08:04:30

+3

這就像說android:layout_width =「500dp」說android:maxWidth =「500dp」一樣有效。它們都強調視圖的特定尺寸。 – 2013-05-15 16:08:05

3

沒有辦法設置maxHeight。但是你可以設置高度。

要做到這一點,你需要發現你scrollView的每個項目的高度。之後,只需將您的scrollView高度設置爲numberOfItens * heightOfItem。

要發現一個項目的高度,這樣做:

View item = adapter.getView(0, null, scrollView); 
item.measure(0, 0); 
int heightOfItem = item.getMeasuredHeight(); 

要設置高度做到這一點:

// if the scrollView already has a layoutParams: 
scrollView.getLayoutParams().height = heightOfItem * numberOfItens; 
// or 
// if the layoutParams is null, then create a new one. 
scrollView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, heightOfItem * numberOfItens)); 
1

如果有人使用精確值的LayoutParams例如考慮

setLayoutParams(new LayoutParams(Y, X); 

請記住考慮設備顯示的密度,否則在不同設備上可能會出現非常奇怪的行爲。 E.g:

Display display = getWindowManager().getDefaultDisplay(); 
DisplayMetrics d = new DisplayMetrics(); 
display.getMetrics(d); 
setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, (int)(50*d.density))); 
53

爲了創建一個ScrollViewListView你只需要創建一個圍繞它一個透明的LinearLayout以你想要的maxHeight是什麼高度maxHeight。然後您將ScrollView的高度設置爲wrap_content。這將創建一個ScrollView,它看起來會增長,直到其高度等於父LinearLayout。

+2

這對防止滾動內容的對話框擴展到屏幕的整個高度非常有用。 – 2013-12-05 00:36:30

+0

小建議將使用一個FrameLayout而不是一個LinearLayout,但我懷疑它很重要。 – 2013-12-05 00:37:08

+36

如果某些佈局出現在scrollview下面,那麼這個技巧不會工作 – 2014-03-05 04:36:36

64

這些解決方案都不能用於我所需要的,它是一個設置爲wrap_content的滾動視圖,但有一個maxHeight,因此它會在某個點後停止展開並開始滾動。我只是簡單地覆蓋了ScrollView中的onMeasure方法。

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(300, MeasureSpec.AT_MOST); 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
} 

這可能不適用於所有情況,但它肯定會給我佈局所需的結果。它還解決了madhu的評論。

如果目前的一些佈局滾動視圖,然後這招不會工作如下 - 馬杜3月5日在4:36

+1

何時不能工作?這似乎是一個非常乾淨的解決方案。讓我想知道他們爲什麼沒有將它實現到xml中。 – 2014-06-02 06:03:02

+1

如果您手動將高度設置爲240,則可能無法正常工作。我沒有檢查scrollview所處的模式,因爲我只需要支持1種特定模式(wrap_content)。 – whizzle 2014-06-02 23:44:02

+5

不錯的技巧,只是不要忘記將Dp轉換爲像素 – 2014-08-21 15:32:03

0

首先獲得象素中高度

View rowItem = adapter.getView(0, null, scrollView); 
rowItem.measure(0, 0);  
int heightOfItem = rowItem.getMeasuredHeight(); 

然後只需

Display display = getWindowManager().getDefaultDisplay();  
DisplayMetrics displayMetrics = new DisplayMetrics();  
display.getMetrics(displayMetrics);  
scrollView.getLayoutParams().height = (int)((heightOfItem * 3)*displayMetrics .density); 
0

如果你們想做一個非溢出滾動視圖或列表視圖,只是它與頂視圖和bottomview頂部和底部爲它的RelativeLayout:

<ScrollView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_above="@+id/topview" 
    android:layout_below="@+id/bottomview" > 
+0

這需要更多的信貸。具體但簡單的實現。 – 2016-06-01 03:17:21

25

這爲我工作,使其在XML定製:

MaxHeightScrollView.java:

public class MaxHeightScrollView extends ScrollView { 

private int maxHeight; 
private final int defaultHeight = 200; 

public MaxHeightScrollView(Context context) { 
    super(context); 
} 

public MaxHeightScrollView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    if (!isInEditMode()) { 
     init(context, attrs); 
    } 
} 

public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    if (!isInEditMode()) { 
     init(context, attrs); 
    } 
} 

@TargetApi(Build.VERSION_CODES.LOLLIPOP) 
public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
    super(context, attrs, defStyleAttr, defStyleRes); 
    if (!isInEditMode()) { 
     init(context, attrs); 
    } 
} 

private void init(Context context, AttributeSet attrs) { 
    if (attrs != null) { 
     TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView); 
     //200 is a defualt value 
     maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.MaxHeightScrollView_maxHeight, defaultHeight); 

     styledAttrs.recycle(); 
    } 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST); 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
} 
} 

ATTR。XML

<declare-styleable name="MaxHeightScrollView"> 
     <attr name="maxHeight" format="dimension" /> 
    </declare-styleable> 

例如佈局

<blah.blah.MaxHeightScrollView android:layout_weight="1" 
       app:maxHeight="90dp" 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content"> 
       <EditText android:id="@+id/commentField" 
        android:hint="Say Something" 
        android:background="#FFFFFF" 
        android:paddingLeft="8dp" 
        android:paddingRight="8dp" 
        android:gravity="center_vertical" 
        android:maxLines="500" 
        android:minHeight="36dp" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" /> 
      </blah.blah.MaxHeightScrollView> 
+0

創建自定義視圖絕對是實現此目的的最佳方式。 – 2018-01-10 04:59:27

4

我將在whizzle的答案,如果我能有評論,但認爲它有用的注意,爲了讓我在多窗口的情況下解決這個問題Android中N模式,我需要稍微改變碼本:

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    if(MeasureSpec.getSize(heightMeasureSpec) > maxHeight) { 
     heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST); 
    } 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
} 

這允許佈局來調整爲比最大高度較小,而且也防止它被大於TH e最大高度。我使用的是一個覆蓋RelativeLayout的佈局類,這允許我創建一個自定義對話框,其中ScrollView作爲MaxHeightRelativeLayout的子項,它不擴展屏幕的整個高度,也縮小到適合多邊形中最小的寡婦大小,窗口爲Android N.

0

MaxHeightScrollView自定義視圖

public class MaxHeightScrollView extends ScrollView { 
    private int maxHeight; 

    public MaxHeightScrollView(Context context) { 
     this(context, null); 
    } 

    public MaxHeightScrollView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     init(context, attrs); 
    } 

    private void init(Context context, AttributeSet attrs) { 
     TypedArray styledAttrs = 
       context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView); 
     try { 
      maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.MaxHeightScrollView_mhs_maxHeight, 0); 
     } finally { 
      styledAttrs.recycle(); 
     } 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     if (maxHeight > 0) { 
      heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST); 
     } 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    } 
} 

style.xml

<declare-styleable name="MaxHeightScrollView"> 
    <attr name="mhs_maxHeight" format="dimension" /> 
</declare-styleable> 

使用

<....MaxHeightScrollView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:mhs_maxHeight="100dp" 
    > 

    ... 

</....MaxHeightScrollView> 
0

這裏是我的工作RecyclerView短的解決方案。我裹着我的RecyclerView兩個視圖之間配重等於1,則封閉整個事情的LinearLayout中,像這樣:

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 
    <View 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="1"/> 
    <android.support.v7.widget.RecyclerView 
     android:scrollbars="vertical" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     /> 
    <View 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="1"/> 
</LinearLayout> 

不要忘記使用android:layout_height="wrap_content"爲您RecyclerView。

我希望這可以幫助你們任何人。 :)

相關問題