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

图片预览适配器:

public class ImagePreviewAdapter extends PagerAdapter implements OnPhotoTapListener {

    private Context context;
    private List<String> imageInfo;
    private View currentView;

    ImagePreviewAdapter(Context context, List<String> imageInfo) {
        super();
        this.imageInfo = imageInfo;
        this.context = context;
    }

    @Override
    public int getCount() {
        return imageInfo != null ? imageInfo.size() : 0;
    }

    @Override
    public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        super.setPrimaryItem(container, position, object);
        currentView = (View) object;
    }

    View getPrimaryItem() {
        return currentView;
    }

    ImageView getPrimaryImageView() {
        return (ImageView) currentView.findViewById(R.id.preview);
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_friends_preview, container, false);

        final 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(ImageView view, float x, float y) {
        ((ImagePreviewActivity) context).finishActivityAnim();
    }
}

预览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>

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

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
NineGridImageView 是一个九宫格图片控件。用法1. 首先添加依赖compile 'com.jaeger.ninegridimageview:library:1.0.0'2. 在布局文件中添加 NineGridImageView, 如下所示:nineGridImageView.setAdapter(nineGridViewAdapter);下面是 NineGridImageViewAdapter.class 的源码:public abstract class NineGridImageViewAdapter {     protected abstract void onDisplayImage(Context context, ImageView imageView, T t);     protected void onItemImageClick(Context context, int index, List list) {          }     protected ImageView generateImageView(Context context) {         GridImageView imageView = new GridImageView(context);         imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);         return imageView;     }}T 是你图片的数据类型, 你可以简单的使用 String 类型也可以是你自定义的类型;你必须重写 onDisplayImage(Context context, ImageView imageView, T t) 方法去设置显示图片的方式, 你可以使用 Picasso、Glide 、ImageLoader 或者其他的图片加载库,你也可以给 ImageView 设置一个占位;如果你需要处理图片的点击事件,你可以重写 onItemImageClick(Context context, int index, List list) 方法,加上你自己的处理逻辑;如果你要使用自定义的 ImageView,你可以重写 generateImageView(Context context) 方法, 去生成自定的 ImageView。下面是一段示例代码:private NineGridImageViewAdapter mAdapter = new NineGridImageViewAdapter() { @Override protected void onDisplayImage(Context context, ImageView imageView, Photo photo) { Picasso.with(context)                     .load(photo.getSmallUrl)                     .placeholder(R.drawable.ic_default_image)                     .into(imageView);             }         @Override         protected ImageView generateImageView(Context context) {             return super.generateImageView(context);         }         @Override         protected void onItemImageClick(Context context, int index, List photoList) {            showBigPicture(context, photoList.get(index).getBigUrl());         }     };         ... mNineGridImageView.setAdapter(mAdapter);...4. 给 NineGridImageView 设置图片数据:nineGridImageView.setImagesData(List imageDataList);图片展示:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值