수평 또는 수직 방향에서 임의의 자르기를 지원하는 클래스를 원했기 때문에 이러한 솔루션 중 어느 것도 나에게 적합하지 않았으며 자르기를 동적으로 변경할 수 있기를 원했습니다. 또한 Picasso 호환성이 필요 했고 Picasso는 이미지 드로어 블을 느리게 설정했습니다.
내 구현은 AOSP의 ImageView.java 에서 직접 조정됩니다 . 이를 사용하려면 XML에서 다음과 같이 선언하십시오.
<com.yourapp.PercentageCropImageView
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="matrix"/>
소스에서 최고 자르기를 원하면 다음으로 전화하십시오.
imageView.setCropYCenterOffsetPct(0f);
하단 자르기를 원하시면 다음으로 전화하십시오.
imageView.setCropYCenterOffsetPct(1.0f);
1/3 정도 자르려면 다음으로 전화하십시오.
imageView.setCropYCenterOffsetPct(0.33f);
또한 fit_center와 같은 다른 자르기 방법을 사용하기로 선택한 경우 그렇게 할 수 있으며이 사용자 지정 논리가 트리거되지 않습니다. (다른 구현에서는 자르기 방법 만 사용할 수 있습니다.)
마지막으로 redraw () 메서드를 추가 했으므로 코드에서 자르기 메서드 / scaleType을 동적으로 변경하도록 선택하면 뷰를 강제로 다시 그릴 수 있습니다. 예를 들면 :
fullsizeImageView.setScaleType(ScaleType.FIT_CENTER);
fullsizeImageView.redraw();
사용자 정의 상단 중앙 1/3 자르기로 돌아가려면 다음으로 전화하십시오.
fullsizeImageView.setScaleType(ScaleType.MATRIX);
fullsizeImageView.redraw();
수업은 다음과 같습니다.
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class PercentageCropImageView extends ImageView{
private Float mCropYCenterOffsetPct;
private Float mCropXCenterOffsetPct;
public PercentageCropImageView(Context context) {
super(context);
}
public PercentageCropImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PercentageCropImageView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public float getCropYCenterOffsetPct() {
return mCropYCenterOffsetPct;
}
public void setCropYCenterOffsetPct(float cropYCenterOffsetPct) {
if (cropYCenterOffsetPct > 1.0) {
throw new IllegalArgumentException("Value too large: Must be <= 1.0");
}
this.mCropYCenterOffsetPct = cropYCenterOffsetPct;
}
public float getCropXCenterOffsetPct() {
return mCropXCenterOffsetPct;
}
public void setCropXCenterOffsetPct(float cropXCenterOffsetPct) {
if (cropXCenterOffsetPct > 1.0) {
throw new IllegalArgumentException("Value too large: Must be <= 1.0");
}
this.mCropXCenterOffsetPct = cropXCenterOffsetPct;
}
private void myConfigureBounds() {
if (this.getScaleType() == ScaleType.MATRIX) {
Drawable d = this.getDrawable();
if (d != null) {
int dwidth = d.getIntrinsicWidth();
int dheight = d.getIntrinsicHeight();
Matrix m = new Matrix();
int vwidth = getWidth() - this.getPaddingLeft() - this.getPaddingRight();
int vheight = getHeight() - this.getPaddingTop() - this.getPaddingBottom();
float scale;
float dx = 0, dy = 0;
if (dwidth * vheight > vwidth * dheight) {
float cropXCenterOffsetPct = mCropXCenterOffsetPct != null ?
mCropXCenterOffsetPct.floatValue() : 0.5f;
scale = (float) vheight / (float) dheight;
dx = (vwidth - dwidth * scale) * cropXCenterOffsetPct;
} else {
float cropYCenterOffsetPct = mCropYCenterOffsetPct != null ?
mCropYCenterOffsetPct.floatValue() : 0f;
scale = (float) vwidth / (float) dwidth;
dy = (vheight - dheight * scale) * cropYCenterOffsetPct;
}
m.setScale(scale, scale);
m.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
this.setImageMatrix(m);
}
}
}
@Override
protected boolean setFrame(int l, int t, int r, int b) {
boolean changed = super.setFrame(l, t, r, b);
this.myConfigureBounds();
return changed;
}
@Override
public void setImageDrawable(Drawable d) {
super.setImageDrawable(d);
this.myConfigureBounds();
}
@Override
public void setImageResource(int resId) {
super.setImageResource(resId);
this.myConfigureBounds();
}
public void redraw() {
Drawable d = this.getDrawable();
if (d != null) {
this.setImageDrawable(null);
this.setImageDrawable(d);
}
}
}