Tak satu pun dari solusi ini berhasil untuk saya, karena saya menginginkan kelas yang mendukung pemangkasan sewenang-wenang baik dari arah horizontal maupun vertikal, dan saya ingin itu memungkinkan saya mengubah pemangkasan secara dinamis. Saya juga membutuhkan kompatibilitas Picasso , dan Picasso menyetel gambar yang dapat digambar dengan malas.
Implementasi saya diadaptasi langsung dari ImageView.java di AOSP. Untuk menggunakannya, nyatakan seperti itu dalam XML:
<com.yourapp.PercentageCropImageView
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="matrix"/>
Dari sumber, jika Anda ingin memiliki hasil panen terbaik, hubungi:
imageView.setCropYCenterOffsetPct(0f);
Jika Anda ingin memiliki potongan bawah, hubungi:
imageView.setCropYCenterOffsetPct(1.0f);
Jika Anda ingin mendapatkan 1/3 hasil panen, panggil:
imageView.setCropYCenterOffsetPct(0.33f);
Selain itu, jika Anda memilih untuk menggunakan metode pemotongan lain, seperti fit_center, Anda dapat melakukannya dan tidak ada logika khusus ini yang akan dipicu. (Penerapan lain HANYA memungkinkan Anda menggunakan metode pemangkasannya).
Terakhir, saya menambahkan metode, redraw (), jadi jika Anda memilih untuk mengubah metode krop / scaleType secara dinamis dalam kode, Anda dapat memaksa tampilan untuk menggambar ulang. Sebagai contoh:
fullsizeImageView.setScaleType(ScaleType.FIT_CENTER);
fullsizeImageView.redraw();
Untuk kembali ke pemangkasan sepertiga tengah atas kustom Anda, hubungi:
fullsizeImageView.setScaleType(ScaleType.MATRIX);
fullsizeImageView.redraw();
Ini kelasnya:
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);
}
}
}