2016-07-07 2 views
3

Предположим, что я получаю изображение от API. Я понятия не имею, какие размеры изображения будут раньше времени, но я знаю, что хочу, чтобы это изображение стало src из ImageView. Я установил определенный размер. Я хочу, чтобы любое изображение, которое я получаю из API, чтобы заполнить весь ImageView, я хочу сохранить соотношение сторон, и мне все равно, если одно размер (ширина или высота) становится слишком большим для заданного размера представления, поэтому я использую centerCrop.Как вы масштабируете ImageView, как centerCrop, но сверху?

<ImageView 
    android:layout_width="400px" 
    android:layout_height="300px" 
    android:scaleType="centerCrop" /> 

Если изображение, которое возвращается из API заключается в следующем:

Uncropped, unscaled sample image

Когда он получает установлен как ЦСИ ImageView «s, результат будет что-то похожее на это (заштрихованные части обрезаются):

Sample image scaled and cropped with centerCrop

Однако я получаю запрос, который мы должны ALW ays показывают верхнюю часть изображения и обрезают снизу вверх. Таким образом, желаемый результат что-то вроде этого:

Sample image scaled and cropped from the top

Я уверен, что это возможно, но я веб-парень работает из своей лиги здесь. Будет ли лучше распространять ImageView как-нибудь, или попробовать scaleType="matrix" и setImageMatrix(), или какой-то третий, не имеющий значения вариант?

+0

Возможно дублировать http://stackoverflow.com/questions/6330084/imageview-scaling-top-crop –

+0

Возможные дубликат [Как набор ImageView scaletype в topCrop] (HTTP: // stackoverflow.com/questions/29783358/how-set-imageview-scaletype-to-topcrop) – einverne

ответ

4

Используйте этот TopCropImageView gist

import android.content.Context; 
import android.graphics.Matrix; 
import android.widget.ImageView; 

/** 
* ImageView to display top-crop scale of an image view. 
* 
* @author Chris Arriola 
*/ 
public class TopCropImageView extends ImageView { 

    public TopCropImageView(Context context) { 
     super(context); 
     setScaleType(ScaleType.MATRIX); 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     super.onLayout(changed, left, top, right, bottom); 
     recomputeImgMatrix(); 
    } 

    @Override 
    protected boolean setFrame(int l, int t, int r, int b) { 
     recomputeImgMatrix(); 
     return super.setFrame(l, t, r, b); 
    }  

    private void recomputeImgMatrix() { 
     final Matrix matrix = getImageMatrix(); 

     float scale; 
     final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight(); 
     final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom(); 
     final int drawableWidth = getDrawable().getIntrinsicWidth(); 
     final int drawableHeight = getDrawable().getIntrinsicHeight(); 

     if (drawableWidth * viewHeight > drawableHeight * viewWidth) { 
      scale = (float) viewHeight/(float) drawableHeight; 
     } else { 
      scale = (float) viewWidth/(float) drawableWidth; 
     } 

     matrix.setScale(scale, scale); 
     setImageMatrix(matrix); 
    } 
} 
2

Если вы используете Glide, вы можете использовать пользовательские преобразования. Вы можете использовать мой (который является почти точной копией CenterCrop класса по Glide), который принимает проценты:

https://gist.github.com/bjornson/3ff8888c09908d5c6cc345d0a8e1f6a7

использовать его так же, как и любой другой преобразования растровых изображений:

Glide.with(getContext()) 
    .load(imagePath) 
    .transform(new PositionedCropTransformation(getContext(), 1, 0)) 
    .into(imageView); 

Обычно Необходимые значения: верхнего левого: 0, 0 верхний правый: 0, 1 нижний левый: 1, 0 нижний правый: 1, 1

Использование 0.5f для центра