2015-11-15 2 views
3

У меня возникла проблема с использованием этой библиотеки, чтобы сделать одно из моих изображений в круге динамически. Вот моя попытка:Как создать круговое изображение профиля facebook

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()); На моей схеме он отображается правильно. Однако, когда я пытаюсь вызвать circleProfilePicture, я просто получаю «пустую» фотографию. Похоже, что растровое изображение для изображения не распознается/правильно установлено. Изображение не отображается, как это делает profilePictureView. Любые идеи, почему это может произойти?

+0

который вы использовали? Всегда ставьте много информации, насколько это возможно. Кроме того, вы заглянули в logcat? есть ли какое-то исключение? –

+0

http://stackoverflow.com/questions/23464707/display-fb-profile-pic-in-circular-image-view-in-application –

+0

Похоже, что он ждет ответа на изображение. попытайтесь получить изображение после задержки. –

ответ

8

После использования другой библиотеки изображений (включая Picasso), я закончил использовать Facebook один по имени Fresco. Это намного быстрее с меньшим количеством кода, все работает так, как должно. Поддержка

Фреско:

  • потокового прогрессивных JPEGs
  • отображение анимированных GIF-файлов и WebPs
  • широкие возможности индивидуальной настройки загрузки и отображения изображений

Док говорит также, что

В Android 4. x и ниже, Fresco помещает изображения в специальную область памяти Android. Это позволяет вашему приложению работать быстрее - и страдать от ужасного OutOfMemoryError гораздо реже.

Он также поддерживает закругленный угол, как вы ищите, см. here.

Layout Пример:

 <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 в настоящее время добавляет 2.6Mb к вашему приложению с помощью ProGuard. Вы можете использовать другую библиотеку, такую ​​как Glide, если хотите меньше функциональности.

+0

Это сработало отлично. Спасибо. У меня есть только один вопрос: изображение занимает некоторое время, чтобы фактически отображать из-за сетевой латентности. Есть ли способ разместить какой-либо экран загрузки и не отображать активность изображения, пока изображение не будет загружено? Я не могу понять, потому что я не уверен, что мне нужно отредактировать функцию setUri или я могу поместить код экрана загрузки где-нибудь в этой операции. – user1871869

+0

Во-вторых, я заметил, что если я устанавливаю layout_width и высоту более 50 dp, например, 100 dp каждый, мое изображение размыто. Любая идея о том, как это исправить? – user1871869

+0

картинка будет размытой из-за размера изображения. Изображение находится в px, например 50x50px. Если вы хотите отображать его с большими размерами, вы увидите больше пикселей. Об улучшении загрузки изображений вы можете либо прослушать http://frescolib.org/docs/listening-download-events.html и отобразить, что хотите в конце. Для этого вам нужно будет настроить кэш Fresco и использовать конвейер изображений, см. Http://frescolib.org/docs/configure-image-pipeline.html –

0

Просмотрите эту книгу: https://github.com/hdodenhof/CircleImageView. Я попробовал несколько альтернатив, и этот был счастливым победителем.

+0

Я просто попробовал, и у меня получился тот же результат. У вас есть какой-либо пример кода или что-то, что я делаю неправильно, что изображение не отображается? «Пустая» фотография показывает (общее изображение в facebook), но только не фактическое фото. – user1871869

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"; 
     } 
    } 

Надеется, что это будет работать для вас.

+0

Хорошо, я попробую сегодня. благодаря! – user1871869

4

Я не могу не заметить большинство ответов с просьбой использовать 2 библиотеки, 1 для загрузки изображения и 2-го для его отображения.Ваша цель как разработчика всегда должна заключаться в том, чтобы выполнить вашу задачу с минимальным количеством библиотек, и вот решение, которое нуждается только в 1 библиотеке. Я буду использовать Glide здесь, так как он кэширует изображения точно для нужного вам размера. Я не использовал Fresco поэтому не могу комментировать это, но HERE's что-то на Пикассо против 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 вместо причудливой библиотеки. Не стесняйтесь настраивать его в соответствии с вашими потребностями.

Navigation Drawer header

Шаг 2

Написать пользовательские преобразования, чтобы преобразовать квадратное изображение в круг изображения. Glide использует что-то, называемое Transformations, чтобы вы могли манипулировать изображениями в соответствии с тем, что вам нужно. Прочитайте THIS сообщение для каких преобразований и прочитайте сообщение THIS, чтобы играть с некоторыми пользовательскими преобразованиями. В нашем случае класс преобразования выглядит так.

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 - это ссылка на навигационное меню. Обратите внимание, как 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, дайте мне знать, если вы по-прежнему сталкиваются любые вопросы :) enter image description here

+0

спасибо Vivz, короткое и простое! – user3820753

1

попробовать этот

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

shape.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> 

из положить

enter image description here

Смежные вопросы