3

我无法使用这个库将我的一张图片动态地变成一个圆圈。这是我的尝试:

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" />

我知道当我在我的布局profilePictureView上调用时我的显示正确,它显示正确。profilePictureView.setProfileId(profile.getId());但是,当我尝试调用circularProfilePicture 时,我只是得到一张“空”照片。图像的位图似乎没有被正确识别/设置。图像不显示profilePictureView。任何想法为什么会发生这种情况?

4

5 回答 5

8

在使用了不同的图片库(包括毕加索)之后,我完成了使用 Facebook 的一个名为Fresco的图片库。代码更少,速度更快,一切正常。

壁画支持:

  • 渐进式 JPEG 流
  • 显示动画 GIF 和 WebP
  • 图像加载和显示的广泛定制

医生也这么说

在 Android 4.x 及更低版本中,Fresco 将图像放在 Android 内存的特殊区域中。这可以让您的应用程序运行得更快 - 并且更少地遭受可怕的 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 个用于加载图像,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 回答
1

我通过使用来实现这一点PICASSO library。无需使用CircularImageView 这是我的代码:

Target target = new Target() {

        @Override
        public void onPrepareLoad(Drawable arg0) {
            // Toast.makeText(FragmentChatView.this, "message",
            // Toast.LENGTH_LONG).show();
        }

        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom arg1) {
            bitmap = Bitmap.createScaledBitmap(bitmap, 40, 40, false);
            final Drawable drawImage = new BitmapDrawable(BaseActivity.this
                    .getBaseContext().getResources(), bitmap);
            // ((MaterialNavigationDrawer<Fragment>)
            // FragmentChatView.this).getToolbar().setLogo(drawImage);
            if (iv_logo != null)
                iv_logo.setImageDrawable(drawImage);
        }

        @Override
        public void onBitmapFailed(Drawable arg0) {

        }
    };

    public class CircleTransform implements Transformation {
        @Override
        public Bitmap transform(Bitmap source) {
            int size = Math.min(source.getWidth(), source.getHeight());

            int x = (source.getWidth() - size) / 2;
            int y = (source.getHeight() - size) / 2;

            Bitmap squaredBitmap = Bitmap
                    .createBitmap(source, x, y, size, size);
            if (squaredBitmap != source) {
                source.recycle();
            }

            Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());

            Canvas canvas = new Canvas(bitmap);
            Paint paint = new Paint();
            BitmapShader shader = new BitmapShader(squaredBitmap,
                    BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
            paint.setShader(shader);
            paint.setAntiAlias(true);

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

            squaredBitmap.recycle();
            return bitmap;
        }

        @Override
        public String key() {
            return "circle";
        }
    }

希望它对你有用。

于 2015-11-17T10:52:44.273 回答
0

尝试这个

           <ImageView
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:background="@drawable/shape"
            android:src="@drawable/User"
            android:id="@+id/imageView2" />

形状.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<gradient
    android:angle="0"
    android:centerColor="#ffffff"
    android:centerX="35%"
    android:endColor="#ffffff"
    android:startColor="#ffffff"
    android:type="linear" />
<padding
    android:bottom="20dp"
    android:left="20dp"
    android:right="20dp"
    android:top="20dp" />
<size
    android:width="150dp"
    android:height="150dp" />
<stroke
    android:width="5dp"
    android:color="@color/allThemeBlue" />

</shape>

输出

在此处输入图像描述

于 2016-07-21T05:12:33.820 回答
0

试试这个库:https ://github.com/hdodenhof/CircleImageView 。我尝试了几种替代方案,而这个是幸运的赢家。

于 2015-11-15T02:37:43.673 回答