ImageView你不知道的一些问题

这篇博客探讨了在Android开发中遇到的一个问题:如何处理超长的广告详情图。作者通过创建Demo发现,ImageView无法显示超过一定阈值的图片。在排除了内存溢出的可能后,提出了将长图分成多个部分,使用多个ImageView拼接展示的解决方案,并给出了布局配置和代码实现的初步步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       最近有这样一个需求,点击App的广告轮播图,展示对应的广告详情图(并且详情图要原图展示)。当时在想这需求也太没难度了吧。当拿到美工美眉切好的图,真的有点崩溃,一张老长老长的图。但也没办法,说是领导要求广告必须要这么详细。为了测试内存是否溢出,先写了个小Demo。其具体的主要代码如下:

package com.example.testcontactqq;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class MainActivity extends Activity {
   private ImageView mImage;
   private Context context;
   private Bitmap bitmap;
   private OverScrollView mScrollView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
	}
	
	/**
	 * 初始化控件
	 */
	private void initView(){
		context = MainActivity.this;
		mImage = (ImageView) findViewById(R.id.imageView);
		mScrollView =  (OverScrollView) findViewById(R.id.contact_QQ);
		bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.content);
		mImage.setImageBitmap(bitmap);
	}
	
	
	
}


由于图片比较长,所以最外层加入一个自定义的 Over ScrollView包裹,便于使其能上下滚动。在OverScrollView中加入一展示长图的ImageView。其运行效果图如下所示。



                       效果图

观察运行效果发现,啥都没有。为什么会这样呢?猜想会不会是因为内存溢出或是图片太长展示不出来。查找Log发现并没有报OOM异常,所以OOM就不存在了。紧接着换一张短点的图片,发现能正常展示。由此推测图片太长了一个ImageView展示不出来。为什么会如此呢?查阅相关资料发现ImageView有一个阈值,超过阈值则ImageView不能显示图片,这也很好理解,相当于人类体质都有一个极限,我们是不能超过自己的极限的。对于这种情况该怎么解决呢?想能不能将这张图片分多个ImageView分别展示,最后将所有的ImageView拼接起来,这样一张图片就能完美的展示了。下面就让我们见证这一设想的可行性如何。

第一步:配置相应的布局及实体类。

其具体的代码如下所示。

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="${relativePackage}.${activityClass}" >

    <com.example.testcontactqq.OverScrollView
        android:id="@+id/contact_QQ"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
         >
    </com.example.testcontactqq.OverScrollView>
</RelativeLayout>

ImageBean文件:

package com.example.testcontactqq;

import android.graphics.Bitmap;

/**
 * 图片实体类
 * @author jamy
 *
 */
public class ImageBean {
	//对应图片在List中的下标
	 public String index = null;  
	 //对应List中的bitmap对象
	 public Bitmap bitmap = null; 
	 
	
}

第二步:进行相应代码编写

MainActivity.java:

package com.example.testcontactqq;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class MainActivity extends Activity {
   private Context context;
   private Bitmap bitmap;
   private OverScrollView mScrollView;
   private LinearLayout mContainerLayout;
   private List<ImageBean> mList;
   private int XCount=0;  //X方向上切割数
   private int YCount=3;  //Y方向上切割数
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
	}
	
	/**
	 * 初始化控件
	 */
	private void initView(){
		context = MainActivity.this;
		mScrollView =  (OverScrollView) findViewById(R.id.contact_QQ);
		addLinearLayout();
//		InputStream is=null;
//		try {
//			is = getAssets().open("content.png");
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//		bitmap = BitmapFactory.decodeStream(is);
		bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.content);
		mList = splitBitmap(bitmap,XCount,YCount);
		Log.d("JAMY",mList.size()+"-------size>");
		addImageViews(XCount, YCount);
	}
	
	/**
	 * 添加ScrollView第一层子LinearLayout
	 */
	private void addLinearLayout(){
		mContainerLayout = new LinearLayout(context);
		mContainerLayout.setOrientation(LinearLayout.VERTICAL);
		mContainerLayout.setGravity(Gravity.CENTER_HORIZONTAL);
		mContainerLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
				LayoutParams.MATCH_PARENT));
		mScrollView.addView(mContainerLayout);
	}

	/**
	 * 按需将一bitmap分成多块
	 * @param V_pice  水平方向上的切割塊数
	 * @param H_pice  竖直方向上的切割塊数
	 */
	private void addImageViews(int xCount,int yCount){
		if(xCount == 0 && yCount == 0){
			return;
		}
		for(int i = 0;i <= yCount;i++){
			if(i!=0 && i==yCount){
				break;
			}
			LinearLayout row = new LinearLayout(context);
			row.setOrientation(LinearLayout.VERTICAL);
			row.setLayoutParams(new LinearLayout.LayoutParams(
					LayoutParams.MATCH_PARENT,0 , 1));
			mContainerLayout.addView(row);
			for(int j = 0;j <= xCount;j++){
				if(j!=0 && j==xCount){
					break;
				}
				LinearLayout col = new LinearLayout(context);
				col.setOrientation(LinearLayout.HORIZONTAL);
				col.setGravity(Gravity.CENTER_HORIZONTAL);
				col.setLayoutParams(new LinearLayout.LayoutParams(
						LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1));
				ImageView imageView = new ImageView(context);
				imageView.setAdjustViewBounds(true);
				String index = i+j+""; 
				Log.d("JAMY",index+"----LocalIndex---->");
				Log.d("JAMY",mList.get(Integer.parseInt(index)).index+"----LayoutIndex---->");
				Log.d("JAMY",mList.get(Integer.parseInt(index)).bitmap+"----bitmap---->");
				imageView.setScaleType(ScaleType.FIT_CENTER);
				imageView.setLayoutParams(new LinearLayout.LayoutParams
						(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));  
				imageView.setImageBitmap(mList.get(Integer.parseInt(index)).bitmap);
				
				
				col.addView(imageView);
				row.addView(col);
				
			}
		}
	}
	
	/**
	 * 
	 * @param bitmap 切割的bitmap
	 * @param xCount x方向上切割的数目
	 * @param yCount y方向上切割的数目
	 * @return
	 */
	 public  List<ImageBean> splitBitmap(Bitmap bitmap, int xCount, int yCount) {
		  List<ImageBean> pieces = new ArrayList<ImageBean>(xCount*yCount);  
	        int width = bitmap.getWidth();  
	        int height = bitmap.getHeight();
	        Log.d("JAMY","Width:"+width+"   height:"+height);
	        int pieceWidth=0;  
	        int pieceHeight=0; 
		    if(xCount == 0 && yCount == 0){
		  	      return null;
		    }else if(xCount==0 && yCount!=0){//只竖直方向进行切割
	        	pieceWidth = width;
	        	pieceHeight = height / yCount;  
	        }else if(yCount==0 && xCount!=0){ //只水平方向进行切割
	        	 pieceWidth = width / xCount;  
		         pieceHeight = height;  
	        }else{
	        	 pieceWidth = width / xCount;  
		         pieceHeight = height / yCount;  
	        }
	        for (int i = 0; i <= yCount; i++) { 
	        	if(i!=0 && i==yCount){
	        		break;
	        	}
	            for (int j = 0; j <= xCount; j++) {  
	            	if(j!=0 && j==xCount){
		        		break;
		        	}
	            	ImageBean piece = new ImageBean();  
	                piece.index = i+j+"";  
	                int xValue = j * pieceWidth;  
	                int yValue = i * pieceHeight;  
	                piece.bitmap = Bitmap.createBitmap(bitmap, xValue, yValue,  
	                        pieceWidth, pieceHeight);  
	                Log.d("JAMY","xValue:"+xValue+"  yValue:"+yValue+"  pieceWidth:"+pieceWidth+"  pieceHeight:"+pieceHeight);
	                pieces.add(piece);  
	            }  
	        }  
	       
	        return pieces;  
	    }  
	
}

      
效果图

由此ImageView显示长图的问题以及解决方法就介绍到这。下面我们简单做些总结:
1. 最好不要用一个ImageView显示一张太长图片,很可能造成ImageView超过阈值。
2.在ImageView加载图片之前,要对其进行的压缩,本demo中由于时间匆忙,暂时没有对图片进行处理。

这就是本人对ImageView显示不了长图的一些解决办法,可能您有其他的更好解决办法,欢迎和大家一起交流学习。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值