長圖的展開與收起

長圖的展開與收起

前言

在app的文章中,常常會夾雜着一些特別長的長圖。在閱讀的時候須要滑動好久才能看圖片下方的文字,所以對於長圖只展現圖片上面一部分,而且能夠展開這個功能是很重要的。java

效果

基本思路

利用scaleTypematrix屬性以及直接改變圖片的高度來實現圖片的收起與展開。android

過程

開始嘗試

scaleType屬性介紹

  1. center:保持原圖的大小,顯示在ImageView的中心。當原圖的size大於ImageViewsize,超過部分裁剪處理;
  2. centerInside:以原圖徹底顯示爲目的,將圖片的內容完整居中顯示,經過按比例縮小原圖的size寬(高)等於或小於ImageView的寬(高)。若是原圖的size自己就小於ImageViewsize,則原圖的size不做任何處理,居中顯示在ImageView
  3. centerCrop:以填滿整個ImageView爲目的,將原圖的中心對準ImageView的中心,等比例放大原圖,直到填滿ImageView爲止(指的是ImageView的寬和高都要填滿),原圖超過ImageView的部分做裁剪處理;
  4. matrix:不改變原圖的大小,從ImageView的左上角開始繪製原圖,原圖超過ImageView的部分做裁剪處理;
  5. fitCenter:把原圖按比例擴大或縮小到ImageView的高度,居中顯示;
  6. fitEnd:把原圖按比例擴大(縮小)到ImageView的高度,顯示在ImageView的下部分位置;
  7. fitStart:把原圖按比例擴大(縮小)到ImageView的高度,顯示在ImageView的上部分位置;
  8. fitXY:把原圖按照指定的大小在View中顯示,拉伸顯示圖片,不保持原比例,填滿ImageView

根據以上屬性介紹,能夠知道matrix屬性是咱們要的。設計模式


基本佈局

<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加載的圖片,app

Glide.with(this)
        .load(mainContentBean.getAccessory().get(0))
        .into(ivLongPicture);
複製代碼

點擊事件

直接經過設置imageView的高度來實現圖片的展開與收起,框架

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 {
            // 展開
            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);
        }
    }
});
複製代碼

遇到問題

根據以上的思路以及代碼實現,普通的長圖確實可以作到「展開」和「收起」功能。ide

可是對於原圖寬度超過手機寬度的圖片來講,寬度並無顯示徹底!佈局

對於Glide版本4.0以上,若是寬度過大,會等比例縮放至寬度等於ImageView的寬度,所以並不會有問題,可是咱們的項目用Glide版本是3.7的,並且不容易升級,故此方法不可行。學習


解決

查閱了Glide的文檔,瞭解了Glide能夠在圖片下載完成後對圖片進行一些操做,操做完成以後的圖片天然就成了ImageView認爲的原圖了。this

所以,能夠在加載以前將寬度過大的圖片等比例縮放,縮放完成後再加載到ImageView中去。spa

加載圖片改進

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;

                    //設置matrix
                    Matrix matrix = new Matrix();

                    //設置放縮比例
                    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);
複製代碼

總結

  • ImageViewscaleType屬性的各個屬性值須要瞭解;
  • Glide版本之間的差別須要瞭解;
  • ImageView如何根據scaleType進行圖片切割的須要瞭解(以後有時間閱讀源碼);
  • Glide是一個龐然大物,也是一個很值得學習的框架,須要熟悉掌握(以後有時間閱讀源碼)

Android的優點在於開源,開源的好處在於易於學習,容易更改。對於開源的框架,僅僅是掌握是不夠的,還須要好好的瞭解框架設計的一些設計模式,框架的優缺點等。

相關文章
相關標籤/搜索