2012-02-10 33 views
6

Cập nhật: Kích thước màn hình nhiều thiết bị là một cá trích đỏ - vấn đề chỉ là hình ảnh không mở rộng đúng cách để lấp đầy màn hình - xem nhận xét về câu trả lời của Ivan.Kích thước màn hình thiết bị có hiệu ứng lạ trên ImageViews

Tôi có một file layout với một hình ảnh:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/image" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:adjustViewBounds="true" 
    android:scaleType="centerCrop" /> 

Sau đó, tôi gán đối tượng vẽ được, đó là nhỏ và phải được nhân rộng:

setContentView(R.layout.image_story); 
ImageView image = (ImageView)findViewById(R.id.image); 
image.setImageDrawable(s.image); 

Dưới đây là làm thế nào nó được render trên hai AVD có kích thước màn hình khác nhau. Những điều này nên giống nhau (câu hỏi chi tiết ở phía dưới). Xin lỗi vì những hình ảnh lớn.

với scaleType = centerCrop:

với centerInside

AVDs:

Edit:

Với layout_height = "fill_parent" và scaleType = "centerInside"

Tôi có một AVD 2.1 với các giá trị mặc định, vì vậy màn hình nhỏ và điều này hoạt động chính xác như mong đợi - hình ảnh được phóng to để lấp đầy chiều rộng và chiều cao xem được bao bọc theo chiều cao được chia tỷ lệ.

On Droid Bionic của tôi với một màn hình lâu hơn, và trên bất kỳ AVD với kích thước màn hình tương tự, điều này không work- hình ảnh được thu nhỏ để lấp đầy chiều rộng, nhưng quan điểm được gói vào gốc trước chiều cao hình ảnh tỷ lệ, do đó phần trên cùng và dưới cùng bị cắt.

Tôi không biết tại sao tỷ lệ màn hình của thiết bị sẽ ảnh hưởng đến điều này. Tôi đã thử vô số sự kết hợp của các thông số bố trí và các loại thang đo cố gắng để có được điều này để làm việc trên Bionic. Mọi thứ hoạt động chính xác như mong đợi trên màn hình nhỏ hơn và không hoạt động trên màn hình lớn hơn. Nếu tôi đặt chiều cao hình ảnh một cách rõ ràng trong dp, nó hoạt động như mong đợi, nhưng tôi không bao giờ biết kích thước của hình ảnh (hoặc màn hình) sẽ là gì. Bất kỳ đề xuất?

+0

Ảnh chụp màn hình có thể hữu ích vì tôi không hoàn toàn chắc chắn rằng tôi đang chụp hình đúng. – CaseyB

+0

Ảnh chụp màn hình được thêm vào - điều đó có giúp ích gì không? Màn hình nhỏ hơn cho kết quả mong đợi trong việc mở rộng hình ảnh. Lớn hơn là sử dụng kích thước chưa được đánh số để định kích thước ImageView. –

+0

Bạn có chắc chắn muốn layout_height = wrap_content không? –

Trả lời

4

Đó là một câu hỏi rất tốt thực sự.

Dưới đây là lý do nó hành xử như vậy (từ ImageView.onMeasure(int, int) [line 661]):

// Try adjusting height to be proportional to width 
if (!done && resizeHeight) { 
    int newHeight = (int)((widthSize - pleft - pright) 
      /desiredAspect) + ptop + pbottom; 
    if (newHeight <= heightSize) { // line 661 
     heightSize = newHeight; 
    } // line 663 
} 

nó điều chỉnh độ cao của điểm gì nó làm là chỉ khi tầm cao mới đó là dựa trên tỷ lệ khía cạnh của đối tượng vẽ và điều chỉnh chiều rộng (trong trường hợp của chúng tôi, đó là chiều rộng chính xác của chế độ xem gốc) là nhỏ hơn so với chiều cao được điều chỉnh (mà tại poin này chỉ là chiều cao bản địa có thể vẽ cộng với đệm trong trường hợp của chúng tôi. Hãy cho tôi biết nếu bạn muốn tôi phanh xuống điểm xa hơn.)

Điều tôi không hiểu là tại sao lại có anh ta hạn chế rằng chiều cao mới phải nhỏ hơn. Nó chỉ có ý nghĩa nếu heightSize của chúng ta là EXACTLY hoặc AT_MOST và đã được thiết lập ở phía trên. Trong những trường hợp khác, nó không cần thiết cho nó.

Vì vậy, thực sự thay vì toàn bộ mảnh 661 qua 663 có cần phải có được một cuộc gọi đến

heightSize = resolveAdjustedSize(newHeight, mMaxHeight, heightSpec); 

để đảm bảo chúng tôi chỉ sử dụng hạn chế chiều cao khi nó nên được hạn chế (ví dụ. Chúng tôi đã nhận hạn chế AT_MOST trong heightSpec và giá trị chiều cao trong heightSpec nhỏ hơn chiều cao mới. CHÍNH XÁC không thể xảy ra ở đây trừ khi chúng tôi sử dụng chiều rộng thay đổi.)

Có thể, tôi đã bỏ sót một thứ ở đó. Guys, bất cứ ai đang đọc bài viết này, xin vui lòng góp ý, nếu bạn thấy bất kỳ sai sót trong đó, đặc biệt là nếu bạn là một phần của đội ngũ Android tại Google :)

PS Là một workaround, tôi có thể đề nghị bạn thực hiện một tùy chỉnh ImageView và ghi đè onMeasure (int, int) để đặt giới hạn cho tỷ lệ khung hình chính xác của bạn. Hãy cho tôi biết nếu bạn cần trợ giúp về mã thực tế.

UPD Tôi sẽ viết tên để thu hút sự chú ý của những người dùng Android thông minh tại Google (Tôi hy vọng các chàng trai đã thiết lập Google Alerts): Romain Guy, Roman Nurik, Reto Meier, vui lòng hãy xem cuộc thảo luận này.

+0

Trên thực tế, chỉ khi 'newHeight' nhỏ hơn' heightSize' thì điều chỉnh sau có ý nghĩa, nếu không (nếu nó lớn hơn), chúng ta sẽ điều chỉnh độ rộng ** ** bằng mã mà trước đó là vài dòng. –

+0

Xin lỗi, tôi không hiểu. Có một phần ở trên điều chỉnh chiều rộng, nhưng nó chỉ điều chỉnh newWidth, nó không được sử dụng trong phần mà tôi đã đăng, vì vậy nó sẽ không bù đắp cho newHeight lớn hơn kích thước chiều cao. Ngoài ra, phần đó thực sự phụ thuộc vào chiều rộng đã bị hạn chế bởi thuộc tính layout_width. Nếu layout_with = "fill_parent", phần điều chỉnh chiều rộng sẽ không bao giờ được thực thi vì resizeWidth sẽ luôn là false. Tuy nhiên, chúng tôi vẫn cần phải điều chỉnh chiều cao, tôi không thấy lý do tại sao chỉ trong trường hợp newHeight nhỏ hơn heightSize. Tui bỏ lỡ điều gì vậy? –

+0

[Phần mã này] (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/widget/ImageView.java#647) điều chỉnh 'widthSize'. Lưu ý rằng nếu 'done' được đặt thành true, sẽ không có điều chỉnh độ cao nào được thực hiện. –

0

Như tôi đã hiểu, bạn cần chia tỷ lệ hình ảnh duy trì tỷ lệ khung hình của nó. scaleType="fitCenter" nên cung cấp cho bạn những hành vi mong muốn:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/image" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:adjustViewBounds="true" 
    android:scaleType="fitCenter" /> 

Nếu nó không được, hãy thử thêm này đến file manifest:

<supports-screens 
    android:resizeable="true" 
    android:smallScreens="true" 
    android:normalScreens="true" 
    android:largeScreens="true" 
    android:anyDensity="true" /> 
+0

'fitCenter' không mở rộng hình ảnh lên, chỉ hiển thị hình ảnh ở đầu màn hình ở kích thước gốc (như" fill_parent "lớn và scaleType =" centerInside ", nhưng ở đầu màn hình). Việc thêm 'màn hình hỗ trợ' vào tệp kê khai dường như không có hiệu lực. –

+0

Bạn đã thử gói 'ImageView' vào một số bố cục (' LinearLayout', ví dụ) và sau đó gọi 'setContentView (..)' cho bố cục này? Tôi muốn thử nghiệm với các kết hợp bố cục và bố cục bố cục khác nhau. –

+0

Vâng, không tìm thấy combo phù hợp. Nếu không, tôi đang sử dụng 'setContentView' trên tệp sơ đồ bố trí chỉ với' ImageView' để thử nghiệm và có vẻ giống với 'LinearLayout' với một phần tử con duy nhất. –

Các vấn đề liên quan