1. 程式人生 > >Android超長圖顯示控制元件

Android超長圖顯示控制元件

先上程式碼

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將圖片拼裝起來實現檢視長圖的功能

本來是想做成新浪微博類似的檢視長圖,但卡在了將圖片放大後再滑動時有部分滑不出來,暫時還沒想出怎麼完美解決,暫時就先放個閹割版的吧。