1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Android 仿微信朋友圈图片效果

Android 仿微信朋友圈图片效果

时间:2023-09-18 11:19:28

相关推荐

Android 仿微信朋友圈图片效果

转载:/zhujiabin/p/7184001.html

最新项目需求展示图片,在网上找了一圈,发现这个比较好用,和大家分享一下。但是还有个图片的点击滑动查看功能,等我找到后会在发布博客的

二、使用方法

1、核心类是NineGridLayout,继承自ViewGroup的抽象类,所以我们实际项目使用需要继承它,并要实现3个方法,如下:

package com.example.oaprint.imageShow;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import com.example.oaprint.R;import java.util.ArrayList;import java.util.List;import java.util.TimerTask;/*** 描述:* 作者:HMY* 时间:/5/10*/public abstract class NineGridLayout extends ViewGroup {private static final float DEFUALT_SPACING = 3f;private static final int MAX_COUNT = 9;protected Context mContext;private float mSpacing = DEFUALT_SPACING;private int mColumns;private int mRows;private int mTotalWidth;private int mSingleWidth;private boolean mIsShowAll = false;private boolean mIsFirst = true;private List<String> mUrlList = new ArrayList<>();public NineGridLayout(Context context) {super(context);init(context);}public NineGridLayout(Context context, AttributeSet attrs) {super(context, attrs);TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NineGridLayout);mSpacing = typedArray.getDimension(R.styleable.NineGridLayout_sapcing, DEFUALT_SPACING);typedArray.recycle();init(context);}private void init(Context context) {mContext = context;if (getListSize(mUrlList) == 0) {setVisibility(GONE);}}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {mTotalWidth = right - left;mSingleWidth = (int) ((mTotalWidth - mSpacing * (3 - 1)) / 3);if (mIsFirst) {notifyDataSetChanged();mIsFirst = false;}}/*** 设置间隔** @param spacing*/public void setSpacing(float spacing) {mSpacing = spacing;}/*** 设置是否显示所有图片(超过最大数时)** @param isShowAll*/public void setIsShowAll(boolean isShowAll) {mIsShowAll = isShowAll;}public void setUrlList(List<String> urlList) {if (getListSize(urlList) == 0) {setVisibility(GONE);return;}setVisibility(VISIBLE);mUrlList.clear();mUrlList.addAll(urlList);if (!mIsFirst) {notifyDataSetChanged();}}public void notifyDataSetChanged() {post(new TimerTask() {@Overridepublic void run() {refresh();}});}private void refresh() {removeAllViews();int size = getListSize(mUrlList);if (size > 0) {setVisibility(VISIBLE);} else {setVisibility(GONE);}if (size == 1) {String url = mUrlList.get(0);RatioImageView imageView = createImageView(0, url);//避免在ListView中一张图未加载成功时,布局高度受其他item影响LayoutParams params = getLayoutParams();params.height = mSingleWidth;setLayoutParams(params);imageView.layout(0, 0, mSingleWidth, mSingleWidth);boolean isShowDefualt = displayOneImage(imageView, url, mTotalWidth);if (isShowDefualt) {layoutImageView(imageView, 0, url, false);} else {addView(imageView);}return;}generateChildrenLayout(size);layoutParams();for (int i = 0; i < size; i++) {String url = mUrlList.get(i);RatioImageView imageView;if (!mIsShowAll) {if (i < MAX_COUNT - 1) {imageView = createImageView(i, url);layoutImageView(imageView, i, url, false);} else { //第9张时if (size <= MAX_COUNT) {//刚好第9张imageView = createImageView(i, url);layoutImageView(imageView, i, url, false);} else {//超过9张imageView = createImageView(i, url);layoutImageView(imageView, i, url, true);break;}}} else {imageView = createImageView(i, url);layoutImageView(imageView, i, url, false);}}}private void layoutParams() {int singleHeight = mSingleWidth;//根据子view数量确定高度LayoutParams params = getLayoutParams();params.height = (int) (singleHeight * mRows + mSpacing * (mRows - 1));setLayoutParams(params);}private RatioImageView createImageView(final int i, final String url) {RatioImageView imageView = new RatioImageView(mContext);imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);imageView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {onClickImage(i, url, mUrlList);}});return imageView;}/*** @param imageView* @param url* @param showNumFlag 是否在最大值的图片上显示还有未显示的图片张数*/private void layoutImageView(RatioImageView imageView, int i, String url, boolean showNumFlag) {final int singleWidth = (int) ((mTotalWidth - mSpacing * (3 - 1)) / 3);int singleHeight = singleWidth;int[] position = findPosition(i);int left = (int) ((singleWidth + mSpacing) * position[1]);int top = (int) ((singleHeight + mSpacing) * position[0]);int right = left + singleWidth;int bottom = top + singleHeight;imageView.layout(left, top, right, bottom);addView(imageView);if (showNumFlag) {//添加超过最大显示数量的文本int overCount = getListSize(mUrlList) - MAX_COUNT;if (overCount > 0) {float textSize = 30;final TextView textView = new TextView(mContext);textView.setText("+" + String.valueOf(overCount));textView.setTextColor(Color.WHITE);textView.setPadding(0, singleHeight / 2 - getFontHeight(textSize), 0, 0);textView.setTextSize(textSize);textView.setGravity(Gravity.CENTER);textView.setBackgroundColor(Color.BLACK);textView.getBackground().setAlpha(120);textView.layout(left, top, right, bottom);addView(textView);}}displayImage(imageView, url);}private int[] findPosition(int childNum) {int[] position = new int[2];for (int i = 0; i < mRows; i++) {for (int j = 0; j < mColumns; j++) {if ((i * mColumns + j) == childNum) {position[0] = i;//行position[1] = j;//列break;}}}return position;}/*** 根据图片个数确定行列数量** @param length*/private void generateChildrenLayout(int length) {if (length <= 3) {mRows = 1;mColumns = length;} else if (length <= 6) {mRows = 2;mColumns = 3;if (length == 4) {mColumns = 2;}} else {mColumns = 3;if (mIsShowAll) {mRows = length / 3;int b = length % 3;if (b > 0) {mRows++;}} else {mRows = 3;}}}protected void setOneImageLayoutParams(RatioImageView imageView, int width, int height) {imageView.setLayoutParams(new LayoutParams(width, height));imageView.layout(0, 0, width, height);LayoutParams params = getLayoutParams();// params.width = width;params.height = height;setLayoutParams(params);}private int getListSize(List<String> list) {if (list == null || list.size() == 0) {return 0;}return list.size();}private int getFontHeight(float fontSize) {Paint paint = new Paint();paint.setTextSize(fontSize);Paint.FontMetrics fm = paint.getFontMetrics();return (int) Math.ceil(fm.descent - fm.ascent);}/*** @param imageView* @param url* @param parentWidth 父控件宽度* @return true 代表按照九宫格默认大小显示,false 代表按照自定义宽高显示*/protected abstract boolean displayOneImage(RatioImageView imageView, String url, int parentWidth);protected abstract void displayImage(RatioImageView imageView, String url);protected abstract void onClickImage(int position, String url, List<String> urlList);}

2、我这里用NineGridTestLayout继承NineGridLayout实现,displayOneImage()与displayImage()中的参数都是显示图片需要的,我这里用的是ImageLoader显示图片,当然你也可以用其他的。

package com.example.oaprint.imageShow;import android.content.Context;import android.graphics.Bitmap;import android.util.AttributeSet;import android.view.View;import com.nostra13.universalimageloader.core.ImageLoader;import com.nostra13.universalimageloader.core.assist.FailReason;import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;import java.util.List;/*** 描述:* 作者:HMY* 时间:/5/12*/public class NineGridTestLayout extends NineGridLayout {protected static final int MAX_W_H_RATIO = 3;public NineGridTestLayout(Context context) {super(context);}public NineGridTestLayout(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected boolean displayOneImage(final RatioImageView imageView, String url, final int parentWidth) {ImageLoader.getInstance().displayImage(url, imageView, new ImageLoadingListener() {@Overridepublic void onLoadingStarted(String imageUri, View view) {}@Overridepublic void onLoadingFailed(String imageUri, View view, FailReason failReason) {}@Overridepublic void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {int w = loadedImage.getWidth();int h = loadedImage.getHeight();int newW;int newH;if (h > w * MAX_W_H_RATIO) {//h:w = 5:3newW = parentWidth / 2;newH = newW * 5 / 3;} else if (h < w) {//h:w = 2:3newW = parentWidth * 2 / 3;newH = newW * 2 / 3;} else {//newH:h = newW :wnewW = parentWidth / 2;newH = h * newW / w;}setOneImageLayoutParams(imageView, newW, newH);}@Overridepublic void onLoadingCancelled(String imageUri, View view) {}});return false;}@Overrideprotected void displayImage(RatioImageView imageView, String url) {ImageLoader.getInstance().displayImage(url, imageView);}@Overrideprotected void onClickImage(int i, String url, List<String> urlList) {// Toast.makeText(mContext, "点击了图片" + url, Toast.LENGTH_SHORT).show();}}

RatioImageView.Java

该类有两个功能:

1、是用于ImageView被按下时有变暗效果

2、ImageView的宽高根据设置的比例动态适配高度,如在xml中设置 app:ratio="2" ,ImageView的高度根据其宽度改变,但始终是宽的2倍,该功能在该项目中没有使用。

package com.example.oaprint.imageShow;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Color;import android.graphics.PorterDuff;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.ImageView;import com.example.oaprint.R;/*** 根据宽高比例自动计算高度ImageView* Created by HMY on /4/21.*/public class RatioImageView extends ImageView {/*** 宽高比例*/private float mRatio = 0f;public RatioImageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public RatioImageView(Context context, AttributeSet attrs) {super(context, attrs);TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RatioImageView);mRatio = typedArray.getFloat(R.styleable.RatioImageView_ratio, 0f);typedArray.recycle();}public RatioImageView(Context context) {super(context);}/*** 设置ImageView的宽高比** @param ratio*/public void setRatio(float ratio) {mRatio = ratio;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int width = MeasureSpec.getSize(widthMeasureSpec);if (mRatio != 0) {float height = width / mRatio;heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) height, MeasureSpec.EXACTLY);}super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:Drawable drawable = getDrawable();if (drawable != null) {drawable.mutate().setColorFilter(Color.GRAY,PorterDuff.Mode.MULTIPLY);}break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:Drawable drawableUp = getDrawable();if (drawableUp != null) {drawableUp.mutate().clearColorFilter();}break;}return super.onTouchEvent(event);}}

以上和核心类

在你的recycle view的adapter里面的item布局中使用

<com.example.oaprint.imageShow.NineGridTestLayoutandroid:id="@+id/layout_image_grid"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="8dp"app:sapcing="4dp" />

adapter内:

// 只展示9个,不展示全holder.layoutImageGrid.setIsShowAll(false);holder.layoutImageGrid.setUrlList(mResultBeen.get(position));

注:setUrlList加的是个list

源码地址:/HMY314/NineGridLayout

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。