欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android显示九宫图(自定义圆角,仿微信九宫格图)

程序员文章站 2022-05-13 08:21:36
...

详细解析Android显示九宫图(自定义圆角,仿微信九宫格图)

这是一个自定义九宫格图片框架,里面有设置圆角大小,还有当图片一张的时候控件自定义的大小,图片的间隔,四张图片的时候图片自定义为两行两列等等功能,为了更好解决九宫图问题所定义的一个框架,话不多说,上图上代码:
Android显示九宫图(自定义圆角,仿微信九宫格图)

第一步:自定义控件–NineGridLayout

//  九宫格显示的layout
//  根据图片数量来调整显示
public class NineGridLayout extends ViewGroup {

    /**
     * Context 上下文
     */
    private Context mContext;

    //行
    private int rowCount;       //行

    //列
    private int columnCount;     //列

    //图片之间的间隔
    private int imageSpacing = 10;          //px

    /**
     * 图片大小
     */
    private int imageWidth;
    private int imageHeight;

    /**
     * 当只有一张图片时的长和宽
     */
    private static final int singleWidth = 430;
    private static final int singleHeight = 560;


    /**
     * 图片的Url集合
     */
    private List<String> mImageUrls = new ArrayList<>();
    /**
     * RoundImageView 的集合
     */
    private List<RoundImageView> mImageViews = new ArrayList<>();


    public NineGridLayout(Context context) {
        super(context);
        mContext = context;
    }

    public NineGridLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
    }

    public NineGridLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = 0;
        int totalWidth = width - getPaddingStart() - getPaddingEnd();

        if (mImageUrls.size() > 0) {
            if (mImageUrls.size() == 1) {       //当只有一张图片时的显示大小
                imageWidth = singleWidth;
                imageHeight = singleHeight;
            } else {
                imageWidth = imageHeight = (totalWidth - imageSpacing * 2) / 3;
            }
            width = imageWidth * columnCount + imageSpacing * (columnCount - 1) + getPaddingStart() + getPaddingEnd();
            height = imageHeight * rowCount + imageSpacing * (rowCount - 1) + getPaddingTop() + getPaddingBottom();
        }
        setMeasuredDimension(width, height);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (mImageUrls.size() == 0) {
            return;
        }
        int childCount = mImageUrls.size();
        for (int i = 0; i < childCount; i++) {
            View view = getChildAt(i);
            int rowNum = getRowNum(i + 1);
            int columnNum = getColumnNum(i + 1);

            int left = (imageWidth + imageSpacing) * (columnNum - 1) + getPaddingStart();
            int top = (imageHeight + imageSpacing) * (rowNum - 1) + getPaddingTop();
            int right = left + imageWidth;
            int bottom = top + imageHeight;
            view.layout(left, top, right, bottom);
        }
    }

    /**
     * 获取View所在的row
     */
    private int getRowNum(int i) {
        if (i <= columnCount) {
            return 1;
        } else if (i <= columnCount * 2) {
            return 2;
        } else {
            return 3;
        }
    }

    /**
     * 获取View所在column
     */
    private int getColumnNum(int i) {
        if (i <= columnCount) {
            return i;
        } else if (i <= columnCount * 2) {
            return i - columnCount;
        } else {
            return i - columnCount * 2;
        }
    }


    /**
     * 设置图片的imageUrl 集合
     *
     * @param imageUrl 图片的Url 集合
     */
    public void setImagesData(List<String> imageUrl) {
        this.mImageUrls.clear();
        this.mImageUrls.addAll(imageUrl);
        generateChildrenLayout(imageUrl.size());
    }

    /**
     * 根据图片数量设置图片行列数
     *
     * @param length 图片数量
     */
    private void generateChildrenLayout(int length) {
        if (length <= 3) {
            rowCount = 1;
            columnCount = length;
        } else if (length <= 6) {
            rowCount = 2;
            columnCount = 3;
            if (length == 4) {
                columnCount = 2;
            }
        } else {
            rowCount = 3;
            columnCount = 3;
        }
    }

    /**
     * 刷新控件
     */
    public void notifyDataSetChanged() {
        if (mImageUrls.size() == 0) {
            setVisibility(View.GONE);
            return;
        } else {
            setVisibility(View.VISIBLE);
        }
        removeAllViews();
        int imageCount = mImageUrls.size();
        for (int i = 0; i < imageCount; i++) {
            RoundImageView imageView = getImageView(i);
            addView(imageView);
        }
    }
    /**
     * 这里获得ImageView
     * 如果mImageViews 里面的对应位置已经有了ImageView, 此时取出复用
     * 没有的话则创建一个,  保证了对ImageView 的复用
     *
     * @param position 创建ImageView
     * @return RoundImageView
     */
    private RoundImageView getImageView(final int position) {
        RoundImageView imageView;
        if (position < mImageViews.size()) {
            imageView = mImageViews.get(position);
        } else {
            imageView = createImageView();
            imageView.setOnClickListener(v -> {
                if (listener != null) {
                    listener.onImageItemClick(mContext, NineGridLayout.this, position, mImageUrls);
                }
            });
            mImageViews.add(imageView);
        }
        if (mImageLoader != null) {
            mImageLoader.onDisplayImage(mContext, imageView, mImageUrls.get(position));
        }
        return imageView;
    }

    private RoundImageView createImageView() {
        RoundImageView imageView = new RoundImageView(mContext);
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setImageResource(R.mipmap.ic_default_img1);
        return imageView;
    }


    private static ImageLoader mImageLoader;

    public static void setImageLoader(ImageLoader imageLoader) {
        mImageLoader = imageLoader;
    }

    public interface ImageLoader {
        void onDisplayImage(Context context, ImageView imageView, String url);
    }

    public static ImageLoader getImageLoader() {
        return mImageLoader;
    }


    private OnImageItemClickListener listener;

    public void setOnImageItemClickListener(OnImageItemClickListener listener) {
        this.listener = listener;
    }

    public interface OnImageItemClickListener {
        void onImageItemClick(Context context, NineGridLayout layout, int position, List<String> urls);
    }
}

第二步: 创建xml

<com.liuwurui.lwrlibrary.view.nine.NineGridLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

使用方法(初始化控件):

//该方法最好写在全局中
  RequestOptions options = new RequestOptions()
                .placeholder(R.drawable.ic_default_img1)
                .error(R.drawable.ic_default_img1);
        NineGridLayout.setImageLoader((context, imageView, url) ->
                Glide.with(context).load(url).apply(options).into(imageView));
 nineGridLayout = findViewById(R.id.nine_grid);

模拟数据:

 		List<String> imgList = new ArrayList<>();
  		imgList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576670582403&di=086ebd6227f7dd189de4fb2ac7527dc9&imgtype=0&src=http%3A%2F%2Fb2-q.mafengwo.net%2Fs5%2FM00%2F91%2F06%2FwKgB3FH_RVuATULaAAH7UzpKp6043.jpeg");
        imgList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576670582403&di=d8ba406237a6fa9c66bd116ce57a16d5&imgtype=0&src=http%3A%2F%2Ffile02.16sucai.com%2Fd%2Ffile%2F2014%2F0829%2F372edfeb74c3119b666237bd4af92be5.jpg");
        imgList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576670582402&di=8c7d0e5cac14cb83e375e65664363523&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fforum%2Fw%3D580%2Fsign%3Db57187fbbf3eb13544c7b7b3961fa8cb%2Fa826bd003af33a87dc2bab09c55c10385343b57a.jpg");
        imgList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576670582402&di=fb7f455e1580446974a2281da1175749&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201507%2F04%2F20150704212949_PSfNZ.jpeg");
        imgList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576670582402&di=fcbff0b21e490edf9dab48acd6442ce5&imgtype=0&src=http%3A%2F%2Fimage2.sina.com.cn%2Fent%2Fd%2F2005-06-21%2FU105P28T3D758537F326DT20050621155831.jpg");
        imgList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576670582401&di=bba281ca4809156e28a349e832fc2b49&imgtype=0&src=http%3A%2F%2Fbig5.wallcoo.com%2Fanimal%2Ffly_and_freedom%2Fimages%2F0Vol_096_DY164.jpg");
        imgList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576670582401&di=9430742b08d1626621bd077beddb39c7&imgtype=0&src=http%3A%2F%2Fi2.w.yun.hjfile.cn%2Fdoc%2F201303%2F54c809bf-1eb2-400b-827f-6f024d7d599b_01.jpg");
        imgList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576670582401&di=98a9a1447fb58426758662815af653f4&imgtype=0&src=http%3A%2F%2Ffile02.16sucai.com%2Fd%2Ffile%2F2014%2F1006%2Fe94e4f70870be76a018dff428306c5a3.jpg");
        imgList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576670582400&di=71e97648930ff0178609793acf4fbbdd&imgtype=0&src=http%3A%2F%2Fg.hiphotos.baidu.com%2Fzhidao%2Fpic%2Fitem%2Fac4bd11373f08202b4a9a53a4bfbfbedab641bff.jpg");
       
        nineGridLayout.setImagesData(imgList);
        nineGridLayout.notifyDataSetChanged();

图片圆角定义的控件RoundImageView

public class RoundImageView extends AppCompatImageView {

    private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;

    //默认的圆角半径大小
    private static final int DEFAULT_RADIUS = 5;             //dp
    private int mRadius;

    //矩阵
    private final Matrix mShaderMatrix = new Matrix();
    //bitmap 的画笔
    private final Paint mBitmapPaint = new Paint();
    //绘制的矩形,一般为控件的大小
    private final RectF rectF = new RectF();

    private Bitmap mBitmap;

    public RoundImageView(Context context) {
        this(context, null);
    }

    public RoundImageView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        final int density = (int) context.getResources().getDisplayMetrics().density;
        TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView, defStyleAttr, 0);
        mRadius = t.getDimensionPixelSize(R.styleable.RoundImageView_radius, DEFAULT_RADIUS * density);
        t.recycle();
        init();
    }

    private void init() {
        //5.0以上要设置View的轮廓
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            setOutlineProvider(new OutlineProvider());
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
//        super.onDraw(canvas);
        if (mBitmap == null) {
            return;
        }
        canvas.drawRoundRect(rectF, mRadius, mRadius, mBitmapPaint);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        rectF.set(0, 0, w, h);
        setup();
    }

    @Override
    public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        initializeBitmap();
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        super.setImageDrawable(drawable);
        initializeBitmap();
    }

    @Override
    public void setImageResource(@DrawableRes int resId) {
        super.setImageResource(resId);
        initializeBitmap();
    }

    @Override
    public void setImageURI(Uri uri) {
        super.setImageURI(uri);
        initializeBitmap();
    }

    private void setup() {
        //如果控件的宽度或高度为0
        if (getWidth() == 0 || getHeight() == 0) {
            return;
        }
        if (mBitmap == null) {
            return;
        }
        //设置图片的渲染器   Shader.TileMode.CLAMP 为拉伸模式,拉伸图片的最后一个像素
        BitmapShader mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        //初始化缩放比
        mShaderMatrix.set(null);
        float widthScale = getWidth() * 1.0f / mBitmap.getWidth();
        float heightScale = getHeight() * 1.0f / mBitmap.getHeight();
        mShaderMatrix.setScale(widthScale, heightScale);
        mBitmapShader.setLocalMatrix(mShaderMatrix);

        //设置防锯齿
        mBitmapPaint.setAntiAlias(true);
        mBitmapPaint.setShader(mBitmapShader);
        invalidate();
    }

    private void initializeBitmap() {
        mBitmap = getBitmapFromDrawable(getDrawable());
        setup();
    }

    private Bitmap getBitmapFromDrawable(Drawable drawable) {
        if (drawable == null) {
            return null;
        }
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }
        try {
            Bitmap bitmap;
            if (drawable instanceof ColorDrawable) {
                bitmap = Bitmap.createBitmap(2, 2, BITMAP_CONFIG);
            } else {
                bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
            }
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            drawable.draw(canvas);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private class OutlineProvider extends ViewOutlineProvider {
        @Override
        public void getOutline(View view, Outline outline) {
            outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mRadius);
        }
    }
}

注意:在res/values/strings.xml记得添加圆角自定义控件的属性代码如下

    <declare-styleable name="RoundImageView">
        <attr name="radius"/>
    </declare-styleable>

图片预览的Activity

public class ImagePreviewActivity extends AppCompatActivity implements ViewTreeObserver.OnPreDrawListener {

    public static final String IMAGE_INFO = "IMAGE_INFO";
    public static final String  URL_LIST = "URL_LIST";
    public static final String CURRENT_ITEM = "CURRENT_ITEM";
    public static final int ANIMATE_DURATION = 200;


    private RelativeLayout rootView;

    private ImagePreviewAdapter imagePreviewAdapter;

    private List<ImageInfo> imageInfo;
    private List<String> imageUrls;


    private int currentItem;
    private int imageWidth;
    private int imageHeight;
    private int screenWidth;
    private int screenHeight;


    @Override
    protected void onCreate( Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_friends_image_preview);

        ViewPager viewPager = findViewById(R.id.viewPager);
        final TextView tvPage = findViewById(R.id.tv_page);

        rootView = findViewById(R.id.rootView);

        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        screenWidth = metrics.widthPixels;
        screenHeight = metrics.heightPixels;

        Intent intent = getIntent();

        imageInfo = intent.getParcelableArrayListExtra(IMAGE_INFO);
        imageUrls = intent.getStringArrayListExtra(URL_LIST);
        currentItem = intent.getIntExtra(CURRENT_ITEM, 0);

        imagePreviewAdapter = new ImagePreviewAdapter(this, imageUrls);
        viewPager.setAdapter(imagePreviewAdapter);
        viewPager.setCurrentItem(currentItem);
        viewPager.getViewTreeObserver().addOnPreDrawListener(this);
        viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                currentItem = position;
                tvPage.setText(String.format(getString(R.string.page_select), currentItem + 1, imageInfo.size()));
            }
        });
        tvPage.setText(String.format(getString(R.string.page_select), currentItem + 1, imageUrls.size()));
    }

    @Override
    public void onBackPressed() {
        finishActivityAnim();
    }

    /**
     * 绘制前开始动画
     */
    @Override
    public boolean onPreDraw() {
        rootView.getViewTreeObserver().removeOnPreDrawListener(this);
        final View view = imagePreviewAdapter.getPrimaryItem();
        final ImageView imageView = imagePreviewAdapter.getPrimaryImageView();

        computeImageWidthAndHeight(imageView);
        final ImageInfo imageData = imageInfo.get(currentItem);
        final float vx = imageData.imageViewWidth * 1.0f / imageWidth;
        final float vy = imageData.imageViewHeight * 1.0f / imageHeight;

        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1.0f);
        valueAnimator.addUpdateListener(animation -> {
            long duration = animation.getDuration();
            long playTime = animation.getCurrentPlayTime();
            float fraction = duration > 0 ? (float) playTime / duration : 1f;
            if (fraction > 1) {
                fraction = 1;
            }
            view.setTranslationX(evaluateInt(fraction, imageData.imageViewX + imageData.imageViewWidth / 2 - imageView.getWidth() / 2, 0));
            view.setTranslationY(evaluateInt(fraction, imageData.imageViewY + imageData.imageViewHeight / 2 - imageView.getHeight() / 2, 0));
            view.setScaleX(evaluateFloat(fraction, vx, 1));
            view.setScaleY(evaluateFloat(fraction, vy, 1));
            view.setAlpha(fraction);
            rootView.setBackgroundColor(evaluateArgb(fraction, Color.TRANSPARENT, Color.BLACK));
        });
        addIntoListener(valueAnimator);
        valueAnimator.setDuration(ANIMATE_DURATION);
        valueAnimator.start();
        return true;
    }


    /**
     * Activity 的退场动画
     */
    public void finishActivityAnim() {
        final View view = imagePreviewAdapter.getPrimaryItem();
        final ImageView imageView = imagePreviewAdapter.getPrimaryImageView();
        computeImageWidthAndHeight(imageView);
        final ImageInfo imageData = imageInfo.get(currentItem);
        final float vx = imageData.imageViewWidth * 1.0f / imageWidth;
        final float vy = imageData.imageViewHeight * 1.0f / imageHeight;

        final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1.0f);
        valueAnimator.addUpdateListener(animation -> {
            long duration = animation.getDuration();
            long playTime = animation.getCurrentPlayTime();
            float fraction = duration > 0 ? (float) playTime / duration : 1f;
            if (fraction > 1) {
                fraction = 1;
            }
            view.setTranslationX(evaluateInt(fraction, 0, imageData.imageViewX + imageData.imageViewWidth / 2 - imageView.getWidth() / 2));
            view.setTranslationY(evaluateInt(fraction, 0, imageData.imageViewY + imageData.imageViewHeight / 2 - imageView.getHeight() / 2));
            view.setScaleX(evaluateFloat(fraction, 1, vx));
            view.setScaleY(evaluateFloat(fraction, 1, vy));
//            view.setAlpha(1 - fraction);
            rootView.setBackgroundColor(evaluateArgb(fraction, Color.BLACK, Color.TRANSPARENT));
        });
        addOutListener(valueAnimator);
        valueAnimator.setDuration(ANIMATE_DURATION);
        valueAnimator.start();
    }

    private void computeImageWidthAndHeight(ImageView imageView) {
        //获取图片真实大小
        Drawable drawable = imageView.getDrawable();

        int intrinsicHeight = drawable.getIntrinsicHeight();
        int intrinsicWidth = drawable.getIntrinsicWidth();

        // 计算出与屏幕的比例,用于比较以宽的比例为准还是高的比例为准,因为很多时候不是高度没充满,就是宽度没充满
        float h = screenHeight * 1.0f / intrinsicHeight;
        float w = screenWidth * 1.0f / intrinsicWidth;

        if (h > w) {
            h = w;
        } else {
            w = h;
        }

        // 得出当宽高至少有一个充满的时候图片对应的宽高
        imageHeight = (int) (intrinsicHeight * h);
        imageWidth = (int) (intrinsicWidth * w);
    }

    /**
     * 进场动画监听
     */
    private void addIntoListener(ValueAnimator valueAnimator) {
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                rootView.setBackgroundColor(0x0);
            }
        });
    }

    /**
     * 退场动画监听
     */
    private void addOutListener(ValueAnimator valueAnimator) {
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                finish();
                overridePendingTransition(0, 0);
            }

            @Override
            public void onAnimationStart(Animator animation) {
                rootView.setBackgroundColor(0x0);
            }
        });
    }

    /** Integer 估值器 */
    public Integer evaluateInt(float fraction, Integer startValue, Integer endValue) {
        int startInt = startValue;
        return (int) (startInt + fraction * (endValue - startInt));
    }

    /** Float 估值器 */
    public Float evaluateFloat(float fraction, Number startValue, Number endValue) {
        float startFloat = startValue.floatValue();
        return startFloat + fraction * (endValue.floatValue() - startFloat);
    }

    /** Argb 估值器 */
    public int evaluateArgb(float fraction, int startValue, int endValue) {
        int startA = (startValue >> 24) & 0xff;
        int startR = (startValue >> 16) & 0xff;
        int startG = (startValue >> 8) & 0xff;
        int startB = startValue & 0xff;

        int endA = (endValue >> 24) & 0xff;
        int endR = (endValue >> 16) & 0xff;
        int endG = (endValue >> 8) & 0xff;
        int endB = endValue & 0xff;

        return (startA + (int) (fraction * (endA - startA))) << 24//
                | (startR + (int) (fraction * (endR - startR))) << 16//
                | (startG + (int) (fraction * (endG - startG))) << 8//
                | (startB + (int) (fraction * (endB - startB)));
    }
}

图片预览数据基类:

public class ImageInfo implements Parcelable {

   public int imageViewHeight;
    public  int imageViewWidth;

    public int imageViewX;
    public int imageViewY;

    public ImageInfo() {}

    public ImageInfo(Parcel in) {
        imageViewHeight = in.readInt();
        imageViewWidth = in.readInt();
        imageViewX = in.readInt();
        imageViewY = in.readInt();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(imageViewHeight);
        dest.writeInt(imageViewWidth);
        dest.writeInt(imageViewX);
        dest.writeInt(imageViewY);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<ImageInfo> CREATOR = new Creator<ImageInfo>() {
        @Override
        public ImageInfo createFromParcel(Parcel in) {
            return new ImageInfo(in);
        }

        @Override
        public ImageInfo[] newArray(int size) {
            return new ImageInfo[size];
        }
    };
}

图片预览适配器:

PhotoView photoView = view.findViewById(R.id.preview);

        String url = this.imageInfo.get(position);
        photoView.setOnPhotoTapListener(this);

        NineGridLayout.getImageLoader().onDisplayImage(view.getContext(), photoView, url);
        container.addView(view);
        return view;
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View) object);
    }

    /**
     * 单击关闭
     */
    @Override
    public void onPhotoTap(View view, float v, float v1) {
        ((ImagePreviewActivity) context).finishActivityAnim();
    }

    @Override
    public void onOutsidePhotoTap() {

    }
}

预览Activity的xml:activity_friends_image_preview

// An highlighted block
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootView">

    <com.liuwurui.lwrlibrary.view.nine.HackyViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <TextView
        android:id="@+id/tv_page"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="20dp"
        tools:text="1/4"
        android:textColor="@android:color/white"
        android:textSize="20sp"/>

</RelativeLayout>

HackyViewPager代码如下:

public class HackyViewPager extends ViewPager {

    public HackyViewPager(Context context) {
        super(context);
    }

    public HackyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        try {
            return super.onInterceptTouchEvent(ev);
        } catch (IllegalArgumentException e) {
            return false;
        }
    }
}

预览图片适配器的xml:item_friends_preview

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <uk.co.senab.photoview.PhotoView
        android:id="@+id/preview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</FrameLayout>

细节:尺寸工具类DisplayUtil

public class DisplayUtil {

    private DisplayUtil() {}

    /**
     * 获取屏幕宽度
     */
    public static int getScreenWidth(Context context) {
        return context.getResources().getDisplayMetrics().widthPixels;
    }

    /**
     * 获取屏幕高度
     */
    public static int getScreenHeight(Context context) {
        return context.getResources().getDisplayMetrics().heightPixels;
    }


    //将dp 转为 px
    public static int dp2px(Context context, int dp) {
        return (int) (context.getResources().getDisplayMetrics().density * dp);
    }


    /**
     * 获取状态栏的高度
     */
    public static int getStatusBarHeight(Context context) {
        // 获得状态栏高度
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        return context.getResources().getDimensionPixelSize(resourceId);
    }
}

还有选择多少张:

    <string name="page_select">%d/%d</string>

以上是控件的所有代码,初次写博客,有什么不对的请各位给点意见

相关标签: android