在一定範圍裡,按比例縮放圖片,優化展示效果
阿新 • • 發佈:2019-02-16
在listview中,每個條目有一張圖片,圖片的大小是隨機的,怎麼展示才能美觀。很多人用的方法是,在ImageView中,加屬性
android:adjustViewBounds="true"
android:maxHeight="300dp"
android:maxWidth="300dp"
android:minHeight="150dp"
android:minWidth="150dp"
用來限定ImageView的最大值和最小值。但是,這樣展示的圖片,很多時候會很醜。怎麼才能像微信一樣,有個範圍,超過那個範圍,就壓縮,而且是按比例壓縮。使得展示的很美觀呢?
我不知道微信怎麼寫的,但是儘可能的模仿了。我們專案用的是xUtils3,我這裡針對xUtils3寫。其他理論上類似
效果圖:
說明:
這裡是模仿了微信的展示效果。寬或者高的最大值,不超過螢幕寬度值的一半。我自己設定了寬或者高的最小值,不小於螢幕寬度值的1/6。如上圖的寶劍圖。高是寬的17倍之多,但是高顯示的最大值是螢幕寬的一半,如果此時寬還是它的17分之一,就沒法看了。再比如最下面的貓圖。寬高僅僅80畫素。很小,如果按照原先的展示,也沒法看
程式碼:
1、核心程式碼:處理及展示的工具類:
package com.chen.demo;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.xutils.common.Callback;
import org.xutils.image.ImageOptions;
import org.xutils.x;
/**
* Created by chen on 2016/10/20.
*/
public class BitmapHelper {
public static void displayImg_Fit_XY(final ImageView imageView, String iconUrl, final RelativeLayout rl, final TextView longImgTv, String w, String h, final Activity act, TextView src_width_tv, TextView src_height_tv, TextView src_ratio_tv, TextView result_width_tv, TextView result_height_tv, TextView result_ratio_tv) {
if ("null".equals(iconUrl)) {
iconUrl = null;
}
try {
//寬高的計算結果
final int width_result;
final int height_result;
//原始的寬高值
final int width_src;
final int height_src;
int width = Integer.parseInt(w);
width_src = width;
int height = Integer.parseInt(h);
height_src = height;
//圖片寬或者高的最大值。以螢幕一半為例。
int halfScreenSize = Utils.getScreenSize(act)[0] / 2;
//最小值。避免圖片過小
int minSize = halfScreenSize / 3;
LinearLayout.LayoutParams rl_lp = new LinearLayout.LayoutParams(halfScreenSize / 2, halfScreenSize / 2);
/**
* Sets the margins, in pixels. A call to {@link android.view.View#requestLayout()} needs
* to be done so that the new margins are taken into account. Left and right margins may be
* overriden by {@link android.view.View#requestLayout()} depending on layout direction.
* Margin values should be positive.
*
* @param left the left margin size
* @param top the top margin size
* @param right the right margin size
* @param bottom the bottom margin size
*
* @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginLeft
* @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop
* @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginRight
* @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom
*/
rl_lp.setMargins(0, Utils.dp2px(act, 5), 0, 0);
rl.setLayoutParams(rl_lp);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(halfScreenSize / 2, halfScreenSize / 2);
imageView.setLayoutParams(lp);
//寬高的比例
float ratio = 0;
if (width > halfScreenSize || height > halfScreenSize) {
//需要限制大小
if (width > height) {
//橫圖。得到寬高比例
ratio = 1.0f * height / width;
if (width > halfScreenSize) {
width = halfScreenSize;
}
height = (int) (width * ratio);
if (height < minSize) {
height = minSize;
}
} else if (height >= width) {
//豎圖
ratio = 1.0f * width / height;
if (height > halfScreenSize) {
height = halfScreenSize;
}
width = (int) (height * ratio);
if (width < minSize) {
width = minSize;
}
}
} else {
//長和寬都沒有超過螢幕的一半
if (width > height) {
ratio = 1.0f * height / width;
if (width < minSize) {
width = minSize;
}
height = (int) (width * ratio);
if (height < minSize) {
height = minSize;
}
} else {
ratio = 1.0f * width / height;
if (height < minSize) {
height = minSize;
}
width = (int) (height * ratio);
if (width < minSize) {
width = minSize;
}
}
}
width_result = width;
height_result = height;
src_width_tv.setText("原寬=" + width_src);
src_height_tv.setText("原高=" + height_src);
if (width_src > height_src) {
src_ratio_tv.setText("width / height=" + (1.0f * width_src / height_src));
} else {
src_ratio_tv.setText("height / width=" + (1.0f * height_src / width_src));
}
result_width_tv.setText("結果寬=" + width_result);
result_height_tv.setText("結果高=" + height_result);
if (width_result > height_result) {
result_ratio_tv.setText("結果-width / height=" + (1.0f * width_result / height_result));
} else {
result_ratio_tv.setText("結果-height / width=" + (1.0f * height_result / width_result));
}
ImageOptions imageOptions = new ImageOptions.Builder()
.setIgnoreGif(true)
.setImageScaleType(ImageView.ScaleType.FIT_XY)
.setLoadingDrawableId(R.mipmap.loading)
.setUseMemCache(true)
.build();
x.image().bind(imageView, iconUrl, imageOptions, new Callback.CommonCallback<Drawable>() {
@Override
public void onSuccess(Drawable arg0) {
//寬是高的3倍,或者高是寬的3倍。就視為長圖
if (width_src / height_src >= 3 || height_src / width_src >= 3) {
longImgTv.setVisibility(View.VISIBLE);
} else {
longImgTv.setVisibility(View.GONE);
}
LinearLayout.LayoutParams rl_lp = new LinearLayout.LayoutParams(width_result, height_result);
rl_lp.setMargins(0, Utils.dp2px(act, 5), 0, 0);
rl.setLayoutParams(rl_lp);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(width_result, height_result);
imageView.setLayoutParams(lp);
}
@Override
public void onFinished() {
}
@Override
public void onError(Throwable arg0, boolean arg1) {
imageView.setBackgroundResource(R.mipmap.loadfailed);
}
@Override
public void onCancelled(CancelledException arg0) {
}
});
} catch (Exception e) {
//do something
}
}
}
2、工具類:
package com.chen.demo;
import android.app.Activity;
import android.util.DisplayMetrics;
public class Utils {
/**
* 獲取螢幕尺寸
*
* @param activity Activity
* @return 螢幕尺寸畫素值,下標為0的值為寬,下標為1的值為高
*/
public static int[] getScreenSize(Activity activity) {
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
return new int[]{metrics.widthPixels, metrics.heightPixels};
}
/**
* px轉換dp
*/
public static int px2dp(Activity activity, int px) {
final float scale = activity.getResources().getDisplayMetrics().density;
return (int) (px / scale + 0.5f);
}
/**
* dp轉換px
*/
public static int dp2px(Activity activity, int dip) {
final float scale = activity.getResources().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f);
}
}
3、主activity
package com.chen.demo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
public class MainActivity extends Activity {
ListView listView;
ArrayList<PicBean> list;
MyAdapter myAdapter;
TextView screen_width;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView= (ListView) findViewById(R.id.listView);
screen_width= (TextView) findViewById(R.id.screen_width);
screen_width.setText("螢幕寬度為==="+Utils.getScreenSize(this)[0]);
list=new ArrayList<PicBean>();
myAdapter=new MyAdapter(list,this);
//假裝資料是網路請求,後臺拿到的。網上找的一寫圖片
list.add(new PicBean("http://img1.3lian.com/2015/w7/98/d/22.jpg","1600","900"));
list.add(new PicBean("http://pic2.ooopic.com/11/79/98/31bOOOPICb1_1024.jpg","1024","989"));
list.add(new PicBean("http://qq.yh31.com/tp/ls/201204171232251847.jpg","300","5104"));
list.add(new PicBean("http://img3.3lian.com/2013/s1/74/d/82.jpg","500","682"));
list.add(new PicBean("http://ww3.sinaimg.cn/bmiddle/6d0258b4gw1f71lgzahmaj22p80b4npe.jpg","440","50"));
list.add(new PicBean("http://ww4.sinaimg.cn/square/006iaWqjjw1f8xiqrsp39j30ia0iagmr.jpg","80","80"));
listView.setAdapter(myAdapter);
}
}
4、adapter
package com.chen.demo;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Created by lenovo on 2016/10/20.
*/
public class MyAdapter extends BaseAdapter {
private ArrayList<PicBean> list=new ArrayList<>();
private Activity act;
public MyAdapter(ArrayList<PicBean> list, Activity act) {
this.list = list;
this.act = act;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(act).inflate(R.layout.pic_item_layout, null);
holder.img_rl = (RelativeLayout) convertView.findViewById(R.id.img_rl);
holder.img = (ImageView) convertView.findViewById(R.id.img);
holder.long_img_tv= (TextView) convertView.findViewById(R.id.long_img_tv);
holder.src_width_tv= (TextView) convertView.findViewById(R.id.src_width_tv);
holder.src_height_tv= (TextView) convertView.findViewById(R.id.src_height_tv);
holder.src_ratio_tv= (TextView) convertView.findViewById(R.id.src_ratio_tv);
holder.result_width_tv= (TextView) convertView.findViewById(R.id.result_width_tv);
holder.result_height_tv= (TextView) convertView.findViewById(R.id.result_height_tv);
holder.result_ratio_tv= (TextView) convertView.findViewById(R.id.result_ratio_tv);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
PicBean picBean = list.get(position);
String img_url=picBean.getImgUrl();
String widith = picBean.getWidth();
String height = picBean.getHeight();
//儘可能的把處理交給工具。這樣,展示部分程式碼就簡潔了
BitmapHelper.displayImg_Fit_XY(holder.img,img_url,holder.img_rl,holder.long_img_tv,widith,height,act, holder.src_width_tv,holder.src_height_tv,holder.src_ratio_tv,holder.result_width_tv,holder.result_height_tv,holder.result_ratio_tv);
return convertView;
}
class ViewHolder {
RelativeLayout img_rl;
ImageView img;
//顯示長圖示記的textview
TextView long_img_tv;
//圖片原始寬度
TextView src_width_tv;
//圖片原始高度
TextView src_height_tv;
//原始寬高的比例
TextView src_ratio_tv;
//圖片處理過後的寬度
TextView result_width_tv;
//圖片處理過後的高度
TextView result_height_tv;
//圖片處理後的寬高的比例
TextView result_ratio_tv;
}
}