先上代码
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Rect;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.example.administrator.demo.ScreenUtil;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by WangPing on 2018/1/12.
*/
public class LongPicView extends FrameLayout {
private RecyclerView picList;
private Bitmap[] picArr;
private int contentHeight;
public LongPicView(@NonNull Context context) {
super(context);
init(context);
}
public LongPicView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public LongPicView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
int screenHeight = ScreenUtil.getScreenHeight(context);
int statusHeight = ScreenUtil.getStatusHeight(context);
int naviHeight = ScreenUtil.getNavigationBarHeight(context);
contentHeight = screenHeight - statusHeight - naviHeight;
picList = new RecyclerView(context);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER_HORIZONTAL;
picList.setLayoutParams(params);
picList.setLayoutManager(new LinearLayoutManager(context));
this.addView(picList);
}
public void setImageSource(InputStream is) {
BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
tmpOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, tmpOptions);
int imageWidth = tmpOptions.outWidth;
int imageHeight = tmpOptions.outHeight;
int picListSize;
if (imageHeight % contentHeight == 0) {
picListSize = imageHeight / contentHeight;
} else {
picListSize = imageHeight / contentHeight + 1;
}
picArr = new Bitmap[picListSize];
try {
BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(is, false);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
for (int i = 0; i < picListSize; i++) {
Rect rect = new Rect();
rect.left = 0;
rect.top = contentHeight * i;
rect.right = imageWidth;
int clipHeight = contentHeight * (i + 1);
if (clipHeight >= imageHeight) {
rect.bottom = imageHeight;
} else {
rect.bottom = clipHeight;
}
Bitmap bitmap = bitmapRegionDecoder.decodeRegion(rect, options);
picArr[i] = bitmap;
}
} catch (IOException e) {
e.printStackTrace();
}
PicAdapter adapter = new PicAdapter();
picList.setAdapter(adapter);
}
private class PicAdapter extends RecyclerView.Adapter<ViewHolder> {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final ImageView image = new ImageView(parent.getContext());
image.setScaleType(ImageView.ScaleType.FIT_XY);
return new ViewHolder(image);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
ImageView iv = (ImageView) holder.itemView;
iv.setImageBitmap(picArr[position]);
}
@Override
public int getItemCount() {
return picArr.length;
}
}
static class ViewHolder extends RecyclerView.ViewHolder {
ViewHolder(View itemView) {
super(itemView);
}
}
}
原理是使用BitmapRegionDecoder来实现对图片的区域选择,通过Rect得到图片中想要部分的Bitmap
将原图拆分,再使用RecyclerView将图片拼装起来实现查看长图的功能
本来是想做成新浪微博类似的查看长图,但卡在了将图片放大后再滑动时有部分滑不出来,暂时还没想出怎么完美解决,暂时就先放个阉割版的吧。