1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Android实现九宫格图片控件

Android实现九宫格图片控件

时间:2020-01-30 04:17:11

相关推荐

Android实现九宫格图片控件

没有效果图的示例简直就是扯淡

下篇文章实现安卓实现微信朋友圈查看图片功能,跟微信朋友圈效果一样,支持拖拽,支持动画,代码完全开发,完全自定义,可自行修改效果。快去看看吧

控件通过完全自定义的方式实现:具有以下功能:

完全动态适配手机屏幕宽度;单张图片时可以自定义图片大小;可自定义多张图片之间的间距;可自定义最大限制长度;多张图片时根据间距自动计算图片的大小;可实现图片的点击功能;可实现图片的长按功能;大于9张图片时+n布局自动展示;+n布局可以在代码中自动修改样式;支持Glide等多种图片加载框架。

直接看代码吧。

图片加载布局自定义类:

MyCustomImageLayout.class

import android.content.Context;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.SparseArray;import android.util.TypedValue;import android.view.Gravity;import android.view.View;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.TextView;import androidx.annotation.Nullable;import androidx.recyclerview.widget.RecyclerView;import com.bumptech.glide.Glide;import java.util.ArrayList;import java.util.List;/*** 根据ImageWatcher源码修改得来** @author 小口口* 自定义显示图片(可显示一张、多张。如果大于9张最后一张会显示+n)*/public class MyCustomImageLayout extends FrameLayout implements View.OnClickListener, View.OnLongClickListener {//默认布局最多显示9个,超出显示+n//也可以通过函数setMaxCount()方法设置public int MAX_DISPLAY_COUNT = 9;//image布局private LayoutParams lpChildImage =new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);//单张最大宽高private int mSingleMaxSize;//多张图片间距private int mSpace;//显示view的集合private final List<ImageView> iPictureList = new ArrayList<>();private final SparseArray<ImageView> mVisiblePictureList = new SparseArray<>();//如果超出9个,最后一个+n显示的布局private final TextView tOverflowCount;//图片点击事件回调private Callback mCallback;//图片长按点击事件回调private OnImageLongClickListener clickListener;//图片数据集合private List<String> mImageDataLists = new ArrayList<>();/*** 构造方法(用来处理view初始化)** @param context* @param attrs*/public MyCustomImageLayout(Context context, @Nullable AttributeSet attrs) {super(context, attrs);//获取单张图片默认大小和间距DisplayMetrics mDisplayMetrics = context.getResources().getDisplayMetrics();//本来是要也可以通过配置xml文件实现//这里用的是直接设置的//设置单个图片大小为200dp*200dp//这是多个图片之间的间距为5dpmSingleMaxSize = (int) (TypedValue.applyDimension(PLEX_UNIT_DIP, 200, mDisplayMetrics));mSpace = (int) (TypedValue.applyDimension(PLEX_UNIT_DIP, 5, mDisplayMetrics));//开始创建9个imageviewfor (int i = 0; i < MAX_DISPLAY_COUNT; i++) {ImageView squareImageView = new SquareImageView(context);squareImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);squareImageView.setVisibility(View.GONE);//new图片的时候添加点击事件和长按事件squareImageView.setOnClickListener(this);squareImageView.setOnLongClickListener(this);addView(squareImageView);iPictureList.add(squareImageView);}//如果图片个数大于9张,这个就是第九个图片上面的+n的view创建tOverflowCount = new TextView(context);tOverflowCount.setTextColor(0xFFFFFFFF);tOverflowCount.setTextSize(24);tOverflowCount.setGravity(Gravity.CENTER);tOverflowCount.setBackgroundColor(0x66000000);tOverflowCount.setVisibility(View.GONE);addView(tOverflowCount);}/*** 这个是单张图片的调用方法(废弃了)** @param list*/public void setUrlData(String list) {mImageDataLists.clear();mImageDataLists.add(list);mSingleMaxSize = (int) (getWidth() * 1f - mSpace);notifyDataChanged();}/*** 设置图片数据方法* 目前是用的list集合,如果是数组的话请自行转* @param list*/public void setUrlListData(List<String> list) {mImageDataLists.clear();mImageDataLists = list;notifyDataChanged();}/*** 数据刷新*/private void notifyDataChanged() {//图片的长度final int urlListSize = mImageDataLists.size();//如果图片不为空并且大于0,显示布局setVisibility(mImageDataLists.size() < 1 ? View.GONE : View.VISIBLE);if (mImageDataLists.size() < 1) {return;}//默认每行显示3个图片int column = 3;//判断每行需要显示的图片数量if (urlListSize == 1) {column = 1;} else if (urlListSize == 4) {column = 2;}//默认显示1行int row = 1;//判断需要显示的行数if (urlListSize > 6) {row = 3;} else if (urlListSize > 3) {row = 2;} else if (urlListSize > 0) {row = 1;}//确认每个图片显示的大小了int imageSize = 0;//如果是一个图片的话,就显示默认的单个图片大小if (urlListSize == 1) {imageSize = mSingleMaxSize;} else if (urlListSize == 2 || urlListSize == 4) {//如果是两张或者四张的话,每行显示2个,显示2行imageSize = (int) ((getWidth() * 1f - mSpace) / 2);} else {imageSize = (int) ((getWidth() * 1f - mSpace) / 3); //否则显示3个}//将图片大小给到子布局(宽高设置为一样的)lpChildImage.width = imageSize;lpChildImage.height = imageSize;//如果图片数量大于MAX_DISPLAY_COUNT值,显示+n布局tOverflowCount.setVisibility(urlListSize > MAX_DISPLAY_COUNT ? View.VISIBLE : View.GONE);tOverflowCount.setText("+ " + (urlListSize - MAX_DISPLAY_COUNT));tOverflowCount.setLayoutParams(lpChildImage);//加载图片之前,清空已显示的图片集合mVisiblePictureList.clear();//遍历图片集合for (int i = 0; i < iPictureList.size(); i++) {//加载每一个图片final ImageView iPicture = iPictureList.get(i);if (i < urlListSize) {iPicture.setVisibility(View.VISIBLE);mVisiblePictureList.put(i, iPicture);iPicture.setLayoutParams(lpChildImage);iPicture.setBackgroundResource(R.mipmap.icon_myphoto_default);Glide.with(getContext()).load(mImageDataLists.get(i)).into(iPicture);iPicture.setTranslationX((i % column) * (imageSize + mSpace));iPicture.setTranslationY((i / column) * (imageSize + mSpace));//设置tag,在图片点击事件的时候可以当作图片的下标iPicture.setTag(i);} else {iPicture.setVisibility(View.GONE);}//第九个单独处理if (i == MAX_DISPLAY_COUNT - 1) {tOverflowCount.setTranslationX((i % column) * (imageSize + mSpace));tOverflowCount.setTranslationY((i / column) * (imageSize + mSpace));}}//根据自布局显示整体布局的高getLayoutParams().height = imageSize * row + mSpace * (row - 1);}/*** 设置回调接口** @param callback*/public void setOnImageClickListener(Callback callback) {mCallback = callback;}/*** 图片的点击事件** @param v*/@Overridepublic void onClick(View v) {if (mCallback != null) {mCallback.onImageClick((ImageView) v, mVisiblePictureList, mImageDataLists);}}/*** 回调事件接口*/public interface Callback {void onImageClick(ImageView i, SparseArray<ImageView> imageGroupList, List<String> urlList);}/*** 长按事件** @param v* @return*/@Overridepublic boolean onLongClick(View v) {if (clickListener != null) {clickListener.onImageLongClick((ImageView) v, mVisiblePictureList, mImageDataLists);}return true;}/*** 回调长按事件接口*/public interface OnImageLongClickListener {void onImageLongClick(ImageView i, SparseArray<ImageView> imageGroupList, List<String> urlList);}/*** 设置长按事件回调接口** @param callback*/public void setOnImageLongClickListener(OnImageLongClickListener callback) {clickListener = callback;}/*** 一旦计算出宽高,刷新数据** @param w* @param h* @param oldw* @param oldh*/@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);notifyDataChanged();}/*** 设置图片的最大数量** @param count*/public void setMaxCount(int count) {this.MAX_DISPLAY_COUNT = count;}}

import android.content.Context;import android.util.AttributeSet;/*** 正方形的ImageView* @author 小口口、*/public class SquareImageView extends androidx.appcompat.widget.AppCompatImageView {public SquareImageView(Context context) {this(context, null);}public SquareImageView(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int widthSize = MeasureSpec.getSize(widthMeasureSpec);setMeasuredDimension(widthSize, widthSize);}}

就这样,代码完了。

Activity这样调用

import android.os.Bundle;import androidx.appcompat.app.AppCompatActivity;import com.google.android.material.snackbar.Snackbar;import java.util.ArrayList;/*** 主界面* @author 小口口、*/public class MainActivity extends AppCompatActivity {//获取布局MyCustomImageLayout mPhotoGridView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mPhotoGridView = findViewById(R.id.image_layout);//监听点击事件mPhotoGridView.setOnImageClickListener((i, imageGroupList, urlList) -> {//图片下标+1int index = (int)i.getTag() + 1;//单个图片的点击事件Snackbar.make(findViewById(R.id.cl), "你点击了第" + index + "个图片", 3000).show();});//监听长按事件mPhotoGridView.setOnImageLongClickListener((i, imageGroupList, urlList) -> {//图片下标+1int index = (int)i.getTag() + 1;//单个图片的长按事件Snackbar.make(findViewById(R.id.cl), "你长按了第" + index + "个图片", 3000).show();});//点击事件findViewById(R.id.txt_1).setOnClickListener(v -> setImage(1));findViewById(R.id.txt_2).setOnClickListener(v -> setImage(2));findViewById(R.id.txt_3).setOnClickListener(v -> setImage(3));findViewById(R.id.txt_4).setOnClickListener(v -> setImage(4));findViewById(R.id.txt_6).setOnClickListener(v -> setImage(6));findViewById(R.id.txt_9).setOnClickListener(v -> setImage(9));findViewById(R.id.txt_15).setOnClickListener(v -> setImage(15));}/*** 根据要求生成集合个数* @param number*/private void setImage(int number){//动态相册集合ArrayList<String> imageList = new ArrayList<>();for (int i = 0; i < number; i++){imageList.add("/it/u=4067224682,690721702&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=450");}//设置数据mPhotoGridView.setUrlListData(imageList);}}

activity的xml文件是这样的

<.imageiwatcherdemo.MyCustomImageLayoutandroid:id="@+id/image_layout"android:layout_width="match_parent"android:layout_height="wrap_content"tools:ignore="MissingConstraints" />

另外还有个图片:icon_myphoto_default.png

呐,代码就这些啦,简单吧~~

附上demo源码。

源码:源码请点这里

如果下不了源码,请联系我。

phone:18588400509

email:mr.cai_cai@

如果有什么问题,欢迎大家指导。并相互联系,希望能够通过文章互相学习。

---财财亲笔

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