3

このライブラリを使用して、画像の 1 つを動的に円にするのに問題があります。これが私の試みです:

private void drawerSetup() {
    Profile profile = Profile.getCurrentProfile();
    ProfilePictureView profilePictureView = (ProfilePictureView) findViewById(R.id.profile_image);
    CircularImageView circularProfilePicture = (CircularImageView)    findViewById(R.id.profile_image_circle);
    if(profilePictureView != null) {
        profilePictureView.setProfileId(profile.getId());
        ImageView imageView = ((ImageView)profilePictureView.getChildAt(0));
        Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
        circularProfilePicture.setImageBitmap(bitmap);
    }
}

レイアウト:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    xmlns:facebook="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/tools"
    android:background="@drawable/side_nav_bar"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:orientation="vertical"
    android:gravity="bottom"
    app:showIn="@layout/activity_news_feed">

<com.facebook.login.widget.ProfilePictureView
    android:id="@+id/profile_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    facebook:com_facebook_preset_size="normal"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:paddingBottom="8dp"
    android:layout_centerInParent="true" />

<com.mikhaellopez.circularimageview.CircularImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    app:border_color="#EEEEEE"
    app:border_width="2dp"
    app:shadow="true"
    app:shadow_radius="10"
    android:id="@+id/profile_image_circle"
    app:shadow_color="#000000"
    android:layout_alignBottom="@+id/profile_image"
    android:layout_toLeftOf="@+id/profile_image"
    android:layout_toStartOf="@+id/profile_image" />

私のレイアウトでは、正しく表示されますprofilePictureViewprofilePictureView.setProfileId(profile.getId());ただし、circularProfilePicture を呼び出そうとすると、単に「空の」写真が表示されます。画像のビットマップが正しく認識/設定されていないようです。のように画像が表示されませんprofilePictureView。なぜこれが起こるのでしょうか?

4

5 に答える 5

8

別の画像ライブラリ (Picasso を含む) を使用した後、Frescoという名前の Facebook のものを使用するようになりました。より少ないコードではるかに高速であり、すべてが正常に機能します。

フレスコのサポート:

  • プログレッシブ JPEG のストリーミング
  • アニメーション GIF と WebP の表示
  • 画像の読み込みと表示の広範なカスタマイズ

ドクターもそう言ってる

Android 4.x 以前では、Fresco は画像を A​​ndroid メモリの特別な領域に配置します。これにより、アプリケーションの実行が高速になり、恐ろしい OutOfMemoryError が発生する頻度が大幅に減少します。

また、検索中の角丸もサポートしています。こちらを参照してください。

レイアウト例:

        <com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/avatarImageView"
            android:layout_width="50dp"
            android:layout_height="50dp"
            fresco:placeholderImageScaleType="centerCrop"
            fresco:placeholderImage="@drawable/photo_placeholder"
            fresco:roundAsCircle="true"/>

Fresco.initialize(this);注:どこか (通常は Application クラス) で呼び出すことを忘れないでください。

また、Fresco は現在、 ProGuard を使用してアプリケーションに2.6Mbを追加していることにも注意してください。機能を減らしたい場合は、Glide などの別のライブラリを使用することもできます。

于 2015-11-18T08:56:01.330 に答える
4

ほとんどの回答で、2 つのライブラリを使用するよう求められていることに気がつきます。開発者としての目標は常に、最小数のライブラリでタスクを完了することです。ここでは、必要なライブラリが 1 つだけのソリューションを示します。ここでは、必要なサイズの画像を正確にキャッシュする Glide を使用します。私は Fresco を使用したことがないのでコメントできませんが、Picasso vs. Glide についてはこちら

ステップ1

レイアウトを作成する

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:theme="@style/ThemeOverlay.AppCompat.Dark">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/image_profile"
        android:layout_width="@dimen/profile_picture_size"
        android:layout_height="@dimen/profile_picture_size"
        android:background="@drawable/image_circle"
        android:paddingTop="@dimen/nav_header_vertical_spacing"
        android:src="@drawable/com_facebook_profile_picture_blank_square" />

    <TextView
        android:id="@+id/text_username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/nav_header_vertical_spacing"
        android:text="@string/placeholder_name"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1"
        android:textColor="@color/colorTextPrimary" />
</LinearLayout>


</RelativeLayout>

これが私のレイアウトの外観です。派手なライブラリの代わりに、プレーンでシンプルな ImageView を使用していることに注意してください。ニーズに合わせて自由に調整してください。

ナビゲーション ドロワー ヘッダー

ステップ2

正方形の画像を円の画像に変換するカスタム変換を記述します。Glide は Transformations と呼ばれるものを使用して、必要に応じて画像を操作できるようにします。変換とは何かについてはこの投稿を読みいくつかのカスタム変換で遊ぶには、この投稿を読んでください。私たちの場合、変換クラスは次のようになります。

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapResource;

public class CropCircleTransform implements Transformation<Bitmap> {

private BitmapPool mBitmapPool;

public CropCircleTransform(Context context) {
    this(Glide.get(context).getBitmapPool());
}

public CropCircleTransform(BitmapPool pool) {
    this.mBitmapPool = pool;
}

@Override
public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {
    Bitmap source = resource.get();
    int size = Math.min(source.getWidth(), source.getHeight());

    int width = (source.getWidth() - size) / 2;
    int height = (source.getHeight() - size) / 2;

    Bitmap bitmap = mBitmapPool.get(size, size, Bitmap.Config.ARGB_8888);
    if (bitmap == null) {
        bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
    }

    Canvas canvas = new Canvas(bitmap);
    Paint paint = new Paint();
    BitmapShader shader =
            new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
    if (width != 0 || height != 0) {
        // source isn't square, move viewport to center
        Matrix matrix = new Matrix();
        matrix.setTranslate(-width, -height);
        shader.setLocalMatrix(matrix);
    }
    paint.setShader(shader);
    paint.setAntiAlias(true);

    float r = size / 2f;
    canvas.drawCircle(r, r, r, paint);

    return BitmapResource.obtain(bitmap, mBitmapPool);
}

@Override public String getId() {
    return "CropCircleTransform()";
}
}

ステップ 3 Glide を使用して、画像をこのレイアウトに読み込みます。Admin は、名前、電子メール、プロフィール写真の URL などの詳細を含むオブジェクトです。mDrawer は、NavigationView への参照です。Glide が手順 2 で定義した変換を使用して、円形の画像効果を実現する方法に注目してください。

public void addHeaderToDrawer(@NonNull Admin admin) {
    View headerView = mDrawer.inflateHeaderView(R.layout.nav_header_main);
    TextView textUserName = (TextView) headerView.findViewById(R.id.text_username);
    ImageView imageProfile = (ImageView) headerView.findViewById(R.id.image_profile);
    textUserName.setText(admin.getName());
    Glide.with(mContext)
            .load(admin.getUrl())
            .asBitmap()
            .transform(new CropCircleTransform(mContext))
            .into(imageProfile);
}

ステップ 4

座ってショーをお楽しみください。また、Facebook からデータを読み込んでいます。まだ問題が発生している場合はお知らせください :) ここに画像の説明を入力

于 2015-11-21T05:19:08.030 に答える
0

このライブラリを試してください: https://github.com/hdodenhof/CircleImageView。いくつかの代替案を試しましたが、これが幸運な勝者でした。

于 2015-11-15T02:37:43.673 に答える