Android實(shí)現(xiàn)長(zhǎng)圖展開(kāi)與收起效果
前言:
在app的文章中,經(jīng)常會(huì)夾雜著一些特別長(zhǎng)的長(zhǎng)圖。在閱讀的時(shí)候需要滑動(dòng)很久才能看圖片下方的文字,因此對(duì)于長(zhǎng)圖只展示圖片上面一部分,并且可以展開(kāi)這個(gè)功能是很重要的。
效果:

基本思路:
利用scaleType的matrix屬性以及直接改變圖片的高度來(lái)實(shí)現(xiàn)圖片的收起與展開(kāi)。
過(guò)程:
開(kāi)始嘗試:
scaleType屬性介紹:
1.center:保持原圖的大小,顯示在ImageView的中心。當(dāng)原圖的size大于ImageView的size,超過(guò)部分裁剪處理;
2.centerInside:以原圖完全顯示為目的,將圖片的內(nèi)容完整居中顯示,通過(guò)按比例縮小原圖的size寬(高)等于或小于ImageView的寬(高)。如果原圖的size本身就小于ImageView的size,則原圖的size不作任何處理,居中顯示在ImageView;
3.centerCrop:以填滿整個(gè)ImageView為目的,將原圖的中心對(duì)準(zhǔn)ImageView的中心,等比例放大原圖,直到填滿ImageView為止(指的是ImageView的寬和高都要填滿),原圖超過(guò)ImageView的部分作裁剪處理;
4.matrix:不改變?cè)瓐D的大小,從ImageView的左上角開(kāi)始繪制原圖,原圖超過(guò)ImageView的部分作裁剪處理;
5.fitCenter:把原圖按比例擴(kuò)大或縮小到ImageView的高度,居中顯示;
6.fitEnd:把原圖按比例擴(kuò)大(縮小)到ImageView的高度,顯示在ImageView的下部分位置;
7.fitStart:把原圖按比例擴(kuò)大(縮小)到ImageView的高度,顯示在ImageView的上部分位置;
8.fitXY:把原圖按照指定的大小在View中顯示,拉伸顯示圖片,不保持原比例,填滿ImageView
根據(jù)以上屬性介紹,可以知道m(xù)atrix屬性是我們要的。
基本布局:
<ImageView android:id="@+id/iv_long_picture" android:layout_width="match_parent" android:layout_height="@dimen/dp_146" android:layout_below="@id/tv_main_content_question" android:adjustViewBounds="true" android:scaleType="matrix" android:src="@color/color_333333" /> <TextView android:id="@+id/tv_expand_collapse" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/iv_long_picture" android:layout_marginBottom="@dimen/dp_16" android:layout_marginTop="@dimen/dp_10" android:drawableEnd="@drawable/down_icon" android:drawablePadding="@dimen/dp_7" android:text="@string/expand_all" android:textColor="@color/color_99" android:textSize="@dimen/sp_14" android:textStyle="bold" android:visibility="gone" />
加載圖片:
使用Glide加載的圖片
Glide.with(this)
.load(mainContentBean.getAccessory().get(0))
.into(ivLongPicture);
點(diǎn)擊事件:
直接通過(guò)設(shè)置imageView的高度來(lái)實(shí)現(xiàn)圖片的展開(kāi)與收起,
tvExpandCollapse.setOnClickListener(new View.OnClickListener() {
boolean expanded = false;
@Override
public void onClick(View v) {
if (expanded) {
// 收起
ViewGroup.LayoutParams params = ivLongPicture.getLayoutParams();
params.width = RelativeLayout.LayoutParams.MATCH_PARENT;
params.height = DensityUtil.dip2px(MainContentActivity.this, 146);
ivLongPicture.setLayoutParams(params);
expanded = false;
tvExpandCollapse.setText(R.string.expand_all);
tvExpandCollapse.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.down_icon, 0);
scMainContent.smoothScrollTo(0, 0);
} else {
// 展開(kāi)
ViewGroup.LayoutParams params = ivLongPicture.getLayoutParams();
params.width = RelativeLayout.LayoutParams.MATCH_PARENT;
params.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
ivLongPicture.setLayoutParams(params);
expanded = true;
tvExpandCollapse.setText(R.string.collapse_all);
tvExpandCollapse.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.upper_icon, 0);
}
}
});
遇到問(wèn)題:
根據(jù)以上的思路以及代碼實(shí)現(xiàn),普通的長(zhǎng)圖確實(shí)能夠做到“展開(kāi)”和“收起”功能。
但是對(duì)于原圖寬度超過(guò)手機(jī)寬度的圖片來(lái)說(shuō),寬度并沒(méi)有顯示完全!
對(duì)于Glide版本4.0以上,如果寬度過(guò)大,會(huì)等比例縮放至寬度等于ImageView的寬度,因此并不會(huì)有問(wèn)題,但是我們的項(xiàng)目用Glide版本是3.7的,而且不容易升級(jí),故此方法不可行。
解決:
查閱了Glide的文檔,了解了Glide可以在圖片下載完成后對(duì)圖片進(jìn)行一些操作,操作完成之后的圖片自然就成了ImageView認(rèn)為的原圖了。
因此,可以在加載之前將寬度過(guò)大的圖片等比例縮放,縮放完成后再加載到ImageView中去。
加載圖片改進(jìn):
Glide.with(this)
.load(mainContentBean.getAccessory().get(0))
.asBitmap()
.listener(new RequestListener<String, Bitmap>() {
@Override
public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {
int imageWidth = resource.getWidth();
int imageHeight = resource.getHeight();
WindowManager manager = (WindowManager) MainContentActivity.this
.getSystemService(Context.WINDOW_SERVICE);
// 屏幕寬度減去margin值
int width = manager.getDefaultDisplay().getWidth() - DensityUtil.dip2px(MainContentActivity.this, 32);
float scaleRate = width * 1.0f / imageWidth;
//設(shè)置matrix
Matrix matrix = new Matrix();
//設(shè)置放縮比例
matrix.setScale(scaleRate, scaleRate);
ivLongPicture.setImageMatrix(matrix);
if (imageHeight * scaleRate > DensityUtil.dip2px(MainContentActivity.this, 146)) {
tvExpandCollapse.setVisibility(View.VISIBLE);
} else {
tvExpandCollapse.setVisibility(View.GONE);
}
return false;
}
})
.into(ivLongPicture);
總結(jié):
- ImageView的scaleType屬性的各個(gè)屬性值需要了解;
- Glide版本之間的差異需要了解;
- ImageView如何根據(jù)scaleType進(jìn)行圖片切割的需要了解(之后有時(shí)間閱讀源碼);
- Glide是一個(gè)龐然大物,也是一個(gè)很值得學(xué)習(xí)的框架,需要熟悉掌握(之后有時(shí)間閱讀源碼)
Android的優(yōu)勢(shì)在于開(kāi)源,開(kāi)源的好處在于易于學(xué)習(xí),容易更改。對(duì)于開(kāi)源的框架,僅僅是掌握是不夠的,還需要好好的了解框架設(shè)計(jì)的一些設(shè)計(jì)模式,框架的優(yōu)缺點(diǎn)等。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android Handler中的休眠喚醒實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了Android Handler中的休眠喚醒實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
Flutter實(shí)現(xiàn)密碼強(qiáng)度校驗(yàn)結(jié)果的示例詳解
我們經(jīng)常在一些網(wǎng)站上看到這樣的密碼強(qiáng)度指示,使用三段線,分別用不同的顏色來(lái)表示弱密碼、中等強(qiáng)度密碼和強(qiáng)密碼,本篇我們就用?Flutter?來(lái)實(shí)現(xiàn)這樣一個(gè)密碼強(qiáng)度校驗(yàn)示例,希望對(duì)大家有所幫助2023-08-08
Android開(kāi)發(fā)中數(shù)據(jù)庫(kù)升級(jí)且表添加新列的方法
這篇文章主要介紹了Android開(kāi)發(fā)中數(shù)據(jù)庫(kù)升級(jí)且表添加新列的方法,結(jié)合具體實(shí)例形式分析了Android數(shù)據(jù)庫(kù)升級(jí)開(kāi)發(fā)過(guò)程中常見(jiàn)問(wèn)題與相關(guān)操作技巧,需要的朋友可以參考下2017-09-09
android開(kāi)發(fā)之listView組件用法實(shí)例簡(jiǎn)析
這篇文章主要介紹了android開(kāi)發(fā)之listView組件用法,結(jié)合實(shí)例形式簡(jiǎn)單分析了listView組件的相關(guān)屬性與使用技巧,需要的朋友可以參考下2016-01-01
Android Activity的啟動(dòng)過(guò)程源碼解析
這篇文章主要介紹了Android Activity的啟動(dòng)過(guò)程源碼解析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
android調(diào)用WebService實(shí)例分析
這篇文章主要介紹了android調(diào)用WebService的方法,以實(shí)例形式較為詳細(xì)的分析了WebService的調(diào)用原理與具體使用方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10

