【问题标题】:Hexagonal Image Transformation With Picasso毕加索的六边形图像转换
【发布时间】:2017-03-28 08:44:07
【问题描述】:

您好,我在我的项目中使用毕加索图像库,现在我遇到了一个问题,我已经用谷歌搜索但没有找到解决方案。我想给我所有的形状一个六边形。

在我之前的应用程序中,我使用了这样的圆形转换:

Picasso.with(mContext).load(obj.getImage())
                .placeholder(R.drawable.logo)
                .error(R.drawable.logo)
                .fit()
                .centerInside()
                .transform(new CircleTransform())
                .into(ivLogo);

现在我想做同样的事情,但这次是六边形,我很难做到这一点,因为我是 android 新手,不知道如何实现。

【问题讨论】:

    标签: android transformation picasso


    【解决方案1】:

    试试这个:

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.PorterDuff;
    import android.graphics.Region;
    import android.util.AttributeSet;
    import android.widget.ImageView;
    
    public class HexagonMaskView extends ImageView {
        private Path hexagonPath;
        private Path hexagonBorderPath;
        private Paint mBorderPaint;
    
        public HexagonMaskView(Context context) {
            super(context);
            init();
        }
    
        public HexagonMaskView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public HexagonMaskView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
            this.hexagonPath = new Path();
            this.hexagonBorderPath = new Path();
    
            this.mBorderPaint = new Paint();
            this.mBorderPaint.setColor(Color.WHITE);
            this.mBorderPaint.setStrokeCap(Paint.Cap.ROUND);
            this.mBorderPaint.setStrokeWidth(50f);
            this.mBorderPaint.setStyle(Paint.Style.STROKE);
        }
    
        public void setRadius(float radius) {
            calculatePath(radius);
        }
    
        public void setBorderColor(int color) {
            this.mBorderPaint.setColor(color);
            invalidate();
        }
    
        private void calculatePath(float radius) {
            float halfRadius = radius / 2f;
            float triangleHeight = (float) (Math.sqrt(3.0) * halfRadius);
            float centerX = getMeasuredWidth() / 2f;
            float centerY = getMeasuredHeight() / 2f;
    
            this.hexagonPath.reset();
            this.hexagonPath.moveTo(centerX, centerY + radius);
            this.hexagonPath.lineTo(centerX - triangleHeight, centerY + halfRadius);
            this.hexagonPath.lineTo(centerX - triangleHeight, centerY - halfRadius);
            this.hexagonPath.lineTo(centerX, centerY - radius);
            this.hexagonPath.lineTo(centerX + triangleHeight, centerY - halfRadius);
            this.hexagonPath.lineTo(centerX + triangleHeight, centerY + halfRadius);
            this.hexagonPath.close();
    
            float radiusBorder = radius - 5f;
            float halfRadiusBorder = radiusBorder / 2f;
            float triangleBorderHeight = (float) (Math.sqrt(3.0) * halfRadiusBorder);
    
            this.hexagonBorderPath.reset();
            this.hexagonBorderPath.moveTo(centerX, centerY + radiusBorder);
            this.hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY + halfRadiusBorder);
            this.hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY - halfRadiusBorder);
            this.hexagonBorderPath.lineTo(centerX, centerY - radiusBorder);
            this.hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY - halfRadiusBorder);
            this.hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY + halfRadiusBorder);
            this.hexagonBorderPath.close();
            invalidate();
        }
    
        @Override
        public void onDraw(Canvas c) {
            c.drawPath(hexagonBorderPath, mBorderPaint);
            c.clipPath(hexagonPath, Region.Op.INTERSECT);
            c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            super.onDraw(c);
        }
    
        @Override
        public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);
            setMeasuredDimension(width, height);
            calculatePath(Math.min(width / 2f, height / 2f) - 10f);
        }
    }

    和xml替换ImageView为

    <?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="match_parent"
        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:background="@android:color/holo_green_dark">
    
        <com.packagename.HexagonMaskView
            android:id="@+id/image"
            android:layout_width="match_parent"
          android:layout_height="match_parent"/>
    
    </RelativeLayout>

    最后继续毕加索代码....

    【讨论】:

    • 在我的适配器类中我是使用 (ImageView) 还是使用 (HexagonMaskView)?
    • 当我使用它时,我的列表活动总是空的,因为没有任何显示,我正在使用数组适配器。甚至在没有毕加索的情况下尝试过,但仍然没有任何显示。
    • 只有HexagonMaskView
    • 您是否为此使用了自定义阵列适配器?我可以看看你在列表中显示图像的代码,这样我就可以在这里看到我做错了什么?
    • 谢谢,现在可以使用了,一开始没有显示,因为我使用 wrap_content 作为宽度和高度。
    【解决方案2】:

    使用 BaseAdapter 后

    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    
    import com.squareup.picasso.Picasso;
    
    import gt.com.greenway.stackoverflow.R;
    import gt.com.greenway.stackoverflow.widgets.HexagonMaskView;
    
    /**
     * Created by Pablo on 27/03/2017.
     */
    public class AdapterL extends BaseAdapter {
    
        private Context context;
        private LayoutInflater inflater;
        private String[] images;
        private String[] titles;
    
        public AdapterL(String[] images, String[] titles, Context context) {
            this.images = images;
            this.titles = titles;
            this.context = context;
            this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
    
        @Override
        public int getCount() {
            return images.length;
        }
    
        @Override
        public Object getItem(int position) {
            return null;
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;
            if (view == null) {
                view = inflater.inflate(R.layout.item_row, null);
    
                HexagonMaskView imageView = (HexagonMaskView) view.findViewById(R.id.ivItemRow);
                TextView textView = (TextView) view.findViewById(R.id.tvItemRow);
    
                Picasso.with(context).load(images[position]).into(imageView);
                textView.setText(titles[position]);
            }
            return view;
        }
    
    
    }

    【讨论】:

      猜你喜欢
      • 2021-05-06
      • 1970-01-01
      • 1970-01-01
      • 2014-04-07
      • 2017-05-17
      • 2018-11-08
      • 1970-01-01
      • 2014-11-24
      • 1970-01-01
      相关资源
      最近更新 更多