本人无聊就喜欢看看微博,发现新浪微博的长图显示很有意思,于是去研究了一下。

首先如果你直接把一张长图set到imageView上,会提示你一个异常 W/OpenGLRenderer(6797): Bitmap too large to be uploaded into a texture (438x5309, max=4096x4096),然后什么都显示不出来,这个时候,你就需要一个东西的帮忙,BitmapRegionDecoder!

下面先上代码

public class MainActivity extends Activity implements OnTouchListener {

/*private LinearLayout container;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//Log.d("drawable", "aa");

container = (LinearLayout)findViewById(R.id.container);

ImageView iv = new ImageView(this);

iv.setBackground(getResources().getDrawable(R.drawable.a));

container.addView(iv,0);

//Log.d("drawable", MyApplication.getmDrawable().toString());

}

}*/

private final Rect mRect = new Rect();

private BitmapRegionDecoder mDecoder;

private ImageView mView;

private DisplayMetrics dm;

private int screenHeight;

private int screenWidth;

//private int downX;

private int downY;

private int startY;

private int showHeight;

private int imgHeight;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//setContentView(R.layout.activity_main);

dm = new DisplayMetrics();

mView = new ImageView(this);

mView.setAdjustViewBounds(true);

mView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

mView.setScaleType(ScaleType.CENTER);

mView.setOnTouchListener(this);

mView.post(new Runnable() {

@Override

public void run() {

getWindowManager().getDefaultDisplay().getMetrics(dm);

screenHeight = dm.heightPixels;

screenWidth = dm.widthPixels;

mRect.set(0, 0, screenWidth, screenHeight);

Bitmap bm = mDecoder.decodeRegion(mRect, null);

mView.setImageBitmap(bm);

showHeight = screenHeight;

startY = 0;

imgHeight = mDecoder.getHeight();

//System.out.println(imgHeight);

//System.out.println(mDecoder.getHeight());

//System.out.println(mView.getWidth());

//System.out.println(mView.getHeight());

}

});

setContentView(mView);

try {

InputStream is = getResources().openRawResource(R.drawable.a);

mDecoder = BitmapRegionDecoder.newInstance(is, true);

} catch (IOException e) {

e.printStackTrace();

}

}

@Override

public boolean onTouch(View v, MotionEvent event) {

final int action = event.getAction() & MotionEvent.ACTION_MASK;

switch (action) {

case MotionEvent.ACTION_DOWN:

//downX = (int) event.getX();;

downY = (int) event.getY();

break;

case MotionEvent.ACTION_MOVE:

//setImageRegion(x, y);

int x = (int) event.getX();

int y = (int) event.getY();

int deltaY = downY - y;

downY = y;

System.out.println(showHeight);

System.out.println(deltaY);

if(showHeight <= screenHeight && deltaY < 0){

break;

}else if(showHeight >= imgHeight + 500 && deltaY > 0){

//System.out.println("else if");

break;

}

showHeight += deltaY;

startY += deltaY;

mRect.set(0, startY, screenWidth, showHeight);

Bitmap bm = mDecoder.decodeRegion(mRect, null);

mView.setImageBitmap(bm);

//System.out.println(deltaY);

break;

}

return true;

}

}

首先

一个ImageView并给它set上onTouchListener

初始化一个BitmapRegionDecoder

InputStream is = getResources().openRawResource(R.drawable.a);

mDecoder = BitmapRegionDecoder.newInstance(is, true);

然后获取屏幕的宽高并使用 mDecoder.decodeRegion(mRect, null);去初始化一张bitmap,这个函数的作用就类似于切图,用BitmapRegionDecoder 把原来很长的图切成只有一屏幕大的图。

最后在onTouch中获得手指滑动的y坐标,根据这个y坐标对切图的rect进行修改,注意要判断边界,不然还是会OOM。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐