Android 自定义ImageView加载图片

时间:2021-03-06 20:37:01


自定义imageview功能:


可以实现设置图片显示的时候,依据本身的比例进行图片的缩放


加载图片效果:


Android 自定义ImageView加载图片


使用ImageLoader来加载 图片:


首先将ImageLoader的jar包关联到项目中

这里加载的是网络图片,所以要添加访问网络的权限

这里加载图片使用的控件是自定义的一个控件


自定义 imageView


import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;

/**
* 自定义的加载图片的ImageView
* 功能:能够根据一个指定的宽高比(ratio)和自己的宽度,动态设置自己的高度
* @author Administrator
*
*/
public class RatioImageView extends ImageView{
//宽高比
private float ratio = 0f;
public RatioImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

//主要设置自定义属性的操作
public RatioImageView(Context context, AttributeSet attrs) {
super(context, attrs);
//获取自定义属性的值,赋值ratio
//参数一是用来设定自定义控件的加载位置
ratio = attrs.getAttributeFloatValue("http://schemas.android.com/apk/res/<span style="font-family: Arial, Helvetica, sans-serif;">com.example.test</span><span style="font-family: Arial, Helvetica, sans-serif;">"</span>
, "ratio", 0f);
}

public RatioImageView(Context context) {
super(context);
}

/**
* 设置ImageView的宽高比
* @param ratio
*/
public void setRatio(float ratio){
this.ratio = ratio;
}

/**
* onMeasure是measure方法引起的回调,而measure方法是父VIew在测量子VIew会调用子的View的measure方法
* 所以widthMeasureSpec和heightMeasureSpec是父VIew在调用子View的measure方法时计算好的
* MeasureSpec: 测量规则,由size和mode2个因素组成:
* size: 就是指定的大小值
* mode: MeasureSpec.AT_MOST : 对应的是warp_content;
* MeasureSpec.EXACTLY : 对应的是具体的dp值,match_parent
* MeasureSpec.UNSPECIFIED: 未定义的,一般用adapter的view的测量中
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//从widthMeasureSpec中反向获取父VIew计算好的size
int width = MeasureSpec.getSize(widthMeasureSpec);

//根据宽高比和width,计算出对应的height
if(ratio!=0){
float height = width/ratio;
//重新组建heightMeasureSpec,传递给super.onMeasure
heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) height,MeasureSpec.EXACTLY);
}

super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

配制自定义属性  values/attrs.xml中


  
<!-- 声明RatioImageView的属性 -->
<declare-styleable name="RatioImageView">
<attr name="ratio" format="float"></attr>
</declare-styleable>



在布局文件中的使用:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:googleplay="http://schemas.android.com/apk/res/com.example.test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:padding="6dp"
android:layout_marginRight="8dp"
android:background="@drawable/selector_list_item"
android:orientation="vertical">

<com.example.test.RatioImageView
android:layout_width="match_parent"
android:id="@+id/iv_image"
android:scaleType="fitXY"
googleplay:ratio="2.42"
android:layout_height="180dp"/>
<!-- <ImageView android:layout_width="match_parent"
android:id="@+id/iv_image"
android:scaleType="fitXY"
android:layout_height="180dp"/> -->

<TextView android:layout_width="match_parent"
android:singleLine="true"
android:layout_marginTop="6dp"
android:id="@+id/tv_des"
android:textSize="16sp"
android:textColor="#000000"
android:text="人之初,性本善,你掏钱,我吃饭"
android:layout_height="wrap_content"/>

</LinearLayout>

</LinearLayout>



在java代码中 


首先初始化Imagloader的相关设置



public class App  extends Application{

@Override
public void onCreate() {

super.onCreate();
//初始化imageLoader
initImageLoader(this);
}
public static void initImageLoader(Context context) {
// This configuration tuning is custom. You can tune every option, you may tune some of them,
// or you can create default configuration by
// ImageLoaderConfiguration.createDefault(this);
// method.
ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context);
config.threadPriority(Thread.NORM_PRIORITY - 2);
//不会在内存中缓存多个大小的图片
config.denyCacheImageMultipleSizesInMemory();
//为了保证图片名称唯一
config.diskCacheFileNameGenerator(new Md5FileNameGenerator());
config.diskCacheSize(50 * 1024 * 1024); // 50 MiB
//内存缓存大小默认是:app可用内存的1/8
config.tasksProcessingOrder(QueueProcessingType.LIFO);
config.writeDebugLogs(); // Remove for release app

// Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(config.build());
//ImageLoader.getInstance().init( ImageLoaderConfiguration.createDefault(this));
}

}

public interface ImageLoaderOptions {
DisplayImageOptions options = new DisplayImageOptions.Builder()
// 加载图片过程中显示哪张图片
.showImageOnLoading(R.drawable.ic_launcher)
// url为空的话显示哪张图片
.showImageForEmptyUri(R.drawable.ic_launcher)
// 加载图片失败显示哪张图片
.showImageOnFail(R.drawable.ic_launcher)
// 在内存中缓存该图片
.cacheInMemory(true)
// 在硬盘中缓存该图片
.cacheOnDisk(true)
//将会对图片进一步缩放,缩放的程度参考ImageVIew的宽高
.imageScaleType(ImageScaleType.EXACTLY)
//该种渲染模式也是比较节省内存的
.bitmapConfig(Bitmap.Config.RGB_565)
// 会识别图片的方向信息
.considerExifParams(true)
// .displayer(new FadeInBitmapDisplayer(800)).build();//渐渐显示的动画效果
.displayer(new RoundedBitmapDisplayer(28)).build();// 圆角的效果

//显示大图的options
DisplayImageOptions pager_options = new DisplayImageOptions.Builder()
// 加载图片过程中显示哪张图片
.showImageOnLoading(R.drawable.ic_launcher)
// url为空的话显示哪张图片
.showImageForEmptyUri(R.drawable.ic_launcher)
// 加载图片失败显示哪张图片
.showImageOnFail(R.drawable.ic_launcher)
// 不在内存中缓存该图片,加载大图时候,如果使用,会造成内存溢出
.cacheInMemory(false)
// 在硬盘中缓存该图片
.cacheOnDisk(true)
//将会对图片进一步缩放,缩放的程度参考ImageVIew的宽高
.imageScaleType(ImageScaleType.EXACTLY)
//该种渲染模式也是比较节省内存的
.bitmapConfig(Bitmap.Config.RGB_565)
// 会识别图片的方向信息
.considerExifParams(true)
//渐渐显示的动画效果
.displayer(new FadeInBitmapDisplayer(800)).build();
//.displayer(new RoundedBitmapDisplayer(28)).build();// 圆角的效果
}



其次 在MainActivity中

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//显示数据的ListView
ListView listView = (ListView) findViewById(R.id.listview);
//初始化数据
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < 50; i++) {
list.add("http://d.3987.com/ftlz_131026/001.jpg");
}
//创建adapter
SubjectAdapter subjectAdapter = new SubjectAdapter(list, this);
//listView中设置Adapter
listView.setAdapter(subjectAdapter);
}


在SubjectAdapter中


public class SubjectAdapter extends BaseAdapter{

private ArrayList<String> maArrayList;
private Context mContext;
public SubjectAdapter(ArrayList<String> list,Context context) {
this.maArrayList = list;
this.mContext = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null){
convertView = View.inflate(mContext, R.layout.adapter_subject, null);
}
ViewHolder holder = ViewHolder.getHolder(convertView);

String imageUrl = maArrayList.get(position);
holder.tv_des.setText("正在测试");

ImageLoader.getInstance().displayImage(imageUrl, holder.iv_image, ImageLoaderOptions.pager_options);

return convertView;
}

static class ViewHolder{
RatioImageView iv_image;
TextView tv_des;

public ViewHolder(View convertView){
iv_image = (RatioImageView) convertView.findViewById(R.id.iv_image);
tv_des = (TextView) convertView.findViewById(R.id.tv_des);
}
public static ViewHolder getHolder(View convertView){
ViewHolder holder = (ViewHolder) convertView.getTag();
if(holder==null){
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}
return holder;
}
}

@Override
public int getCount() {
return maArrayList.size();
}

@Override
public Object getItem(int arg0) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}
}


最后activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#50666666"
tools:context=".MainActivity" >

<ListView
android:cacheColorHint="#00000000"
android:divider="#00000000"
android:dividerHeight="0dp"
android:fadingEdge="none"
android:fastScrollEnabled="false"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
android:smoothScrollbar="true"
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>

</LinearLayout>