Facebook Messenger のように (z の青い Messenger アイコンまたは灰色の Facebook アイコンを使用して) 私の円形の画像ビューを作成するのに役立つライブラリを探しています。彼らはどうやってそれを思いついたのですか?グライドでできますか?そうでない場合は、何を使用しますか?
3 に答える
CircleImageView
/ CircularImageView
/の使用RoundedImageView
はお勧めしません。Glide: の最も基本的な機能と互換性のない Drawable から Bitmap をハッキングしているため、多くの人が問題を報告.crossFade()
しています。
正しいグライド方法は変換を使用することです。ここで十分なものを見つけることができます: https://stackoverflow.com/a/25806229/253468
Glide 4.0 には組み込みの CircleCrop 変換が含まれます。
オーバーレイ アイコン
オーバーレイ アイコンは、変換を使用して追加することもできます。
// .transform(new CircleTransform(context)), new StatusTransform(context, user.getStatus()))
public static class StatusTransform extends BitmapTransformation {
private final Status status;
public StatusTransform(Context context, Status status) {
super(context);
this.status = status;
}
@Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
int w = toTransform.getWidth(), h = toTransform.getHeight();
Bitmap result = pool.get(w, h, Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
canvas.drawBitmap(toTransform);
switch(status) {
case Online:
canvas.draw*(online graphics);
break;
case Offline:
canvas.draw*(offline graphics);
break;
}
return result;
}
@Override public String getId() {
return getClass().getName() + status;
}
}
または単に 2 つImageView
のを指定します。
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/user_profile_size"
android:layout_height="@dimen/user_profile_size"
>
<ImageView
android:id="@id/user_profile"
android:layout_width="@dimen/user_profile_size"
android:layout_height="@dimen/user_profile_size"
/>
<ImageView
android:id="@id/user_status"
android:layout_width="@dimen/user_status_size"
android:layout_height="@dimen/user_status_size"
android:layout_gravity="bottom|end"
/>
</FrameLayout>
どちらにも長所と短所があります: 変換結果はキャッシュできるため、3 つのステータスがある場合、Glide は各ユーザーのプロフィール画像を小さなアイコンで 3 回重ねて保存します。キャッシュされた PNG (円は透過性を強制するため、JPEG ではありません)。2 つの ImageView では、2 つの Glide ロード ライン (または Glide と setImageResource) が必要であり、描画とレイアウトが少し遅くなる可能性があります。したがって、2 つのアプローチを使用して、プロセッサー時間をディスク容量と交換することができます。ImageView アプローチを使用すると、ステータス変更間の遷移をアニメーション化して、ネットワークが悪いためにプロファイル画像の読み込みが遅い場合でもステータスを常に表示することもできます。
メソッドのコードが変更された場合の変換の場合、transform
キャッシュを無効にする必要があります。これは次の方法で実現できます。
.signature(ApplicationVersionSignature.obatain(context)) // every release
// or
.signature(new StringSignature(String.valueOf( System.currentTimeMillies() / (10 * 60 * 1000) ))) // every 10 minutes
getId()
あるいは、この無効化を何らかの方法でメソッドに組み込むことができます。
1.FrescoであるFacebook の画像管理ライブラリをチェックアウトすることをお勧めします。これは、他の画像読み込みライブラリと比較して非常に素晴らしく成熟しています。
2.Fresco には、リンクをサポートし、アニメーション (.gif、.webp) と通常のイメージ (.jpg、.png)SimpleDraweeView
をサポートするカスタム イメージ ビューがあります。Rounded Corners and Circles
BITMAP_MEMORY_CACHE
3.Fresco は、3 層アーキテクチャ ( 、ENCODED_MEMORY_CACHE
および)で画像のキャッシングをすべて処理しますDISK_CACHE
。また、OOM (メモリ不足) の問題も軽減されます。ビュー内の画像が画面外に出ると、ビットマップが自動的にリサイクルされるため、メモリが解放されます。
ターゲットに CircleImageしかない場合は、これを試してみてください。
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class RoundedImageView extends ImageView
{
public RoundedImageView(Context context)
{
super(context);
}
public RoundedImageView(Context context, @Nullable AttributeSet attrs)
{
super(context, attrs);
}
public RoundedImageView(Context context, @Nullable AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public RoundedImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)
{
super(context, attrs, defStyleAttr, defStyleRes);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius)
{
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius)
{
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sbmp = Bitmap.createScaledBitmap(bmp, (int) (bmp.getWidth() / factor), (int) (bmp.getHeight() / factor), false);
}
else
{
sbmp = bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(radius / 2 + 0.7f,
radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
@Override
protected void onDraw(Canvas canvas)
{
Drawable drawable = getDrawable();
if (drawable == null)
{
return;
}
if (getWidth() == 0 || getHeight() == 0)
{
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
}
レイアウトでこれを使用できます:
<mypkg.example.RoundedImageView
android:id="@+id/roundimg"
android:layout_width="54dp"
android:layout_height="54dp"
android:layout_gravity="center"/>
プログラムで文字を設定できます..
Rect textBounds = new Rect();
String text = "N"
Bitmap bitmap = Bitmap.createBitmap(imageView.getLayoutParams().width, imageView.getLayoutParams().height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.DKGRAY);
TextPaint p = new TextPaint();
p.setColor(Color.WHITE);
p.setTextSize(imageView.getLayoutParams().height / 2);
p.setAntiAlias(true);
p.setTextAlign(Paint.Align.LEFT);
p.getTextBounds(text, 0, text.length(), textBounds);
int cx = imageView.getLayoutParams().width / 2;
int cy = imageView.getLayoutParams().height / 2;
canvas.drawText(text, cx - textBounds.exactCenterX(), cy - textBounds.exactCenterY(), p);
imageView.setImageBitmap(bitmap);
または画像..
// image grabbed from an input stream
Bitmap photo = BitmapFactory.decodeStream(inputStream);
imageView.setImageBitmap(photo);
これは便利ですか?詳細とクレジットはこちらAndroidで円形のImageViewを作成するには?