diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index df2488a7ef..c68c1bb325 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -113,7 +113,9 @@ android:screenOrientation="portrait" /> - + { - Intent checkIntent = ViewImageActivity.getViewImageIntent(context, (ArrayList) list, position, entrance); + Intent checkIntent = ImageViewerActivity.getIntent(context, (ArrayList) list, position, entrance); context.startActivity(checkIntent); }); return imageView; diff --git a/app/src/main/java/com/gh/common/view/DraggableBigImageView.kt b/app/src/main/java/com/gh/common/view/DraggableBigImageView.kt new file mode 100644 index 0000000000..5a4b25c0d8 --- /dev/null +++ b/app/src/main/java/com/gh/common/view/DraggableBigImageView.kt @@ -0,0 +1,106 @@ +package com.gh.common.view + +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import android.view.ViewConfiguration +import com.github.piasy.biv.view.BigImageView +import kotlin.math.abs +import kotlin.math.max +import kotlin.math.min + +class DraggableBigImageView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) + : BigImageView(context, attrs, defStyle) { + + private var mInitScale: Float? = null + private val mScaledTouchSlop by lazy { ViewConfiguration.get(context).scaledTouchSlop } + private val mDismissEdge by lazy { height * 0.12 } + private var mSingleTouch = true + private var mFakeDragOffset = 0f + private var mLastX = 0f + private var mLastY = 0f + private var mListener: DragListener? = null + + fun setDragListener(listener: DragListener) { + mListener = listener + } + + override fun dispatchTouchEvent(event: MotionEvent): Boolean { + when (event.actionMasked) { + MotionEvent.ACTION_POINTER_DOWN -> { + setSingleTouch(false) + animate() + .translationX(0f).translationY(0f).scaleX(1f).scaleY(1f) + .setDuration(200).start() + } + MotionEvent.ACTION_DOWN -> if (mInitScale == null) mInitScale = ssiv.scale + MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> up() + MotionEvent.ACTION_MOVE -> { + if (mSingleTouch && ssiv.scale == mInitScale) { + if (mLastX == 0f) mLastX = event.rawX + if (mLastY == 0f) mLastY = event.rawY + val offsetX = event.rawX - mLastX + val offsetY = event.rawY - mLastY + fakeDrag(offsetX, offsetY) + } + } + } + return super.dispatchTouchEvent(event) + } + + private fun fakeDrag(offsetX: Float, offsetY: Float) { + if (mFakeDragOffset == 0f) { + if (offsetY > mScaledTouchSlop) mFakeDragOffset = mScaledTouchSlop.toFloat() + else if (offsetY < -mScaledTouchSlop) mFakeDragOffset = (-mScaledTouchSlop).toFloat() + } + if (mFakeDragOffset != 0f) { + val fixedOffsetY = offsetY - mFakeDragOffset + parent?.requestDisallowInterceptTouchEvent(true) + val fraction = abs(max(-1f, min(1f, fixedOffsetY / height))) + val fakeScale = 1 - min(0.4f, fraction) + scaleX = fakeScale + scaleY = fakeScale + translationY = fixedOffsetY + translationX = offsetX / 2 + mListener?.onDrag(this, fraction) + } + } + + private fun up() { + parent?.requestDisallowInterceptTouchEvent(false) + setSingleTouch(true) + mFakeDragOffset = 0f + mLastX = 0f + mLastY = 0f + + if (abs(translationY) > mDismissEdge) { + mListener?.onRelease(this, scaleX) + } else { + val offsetY = translationY + val fraction = min(1f, offsetY / height) + mListener?.onRestore(this, fraction) + + animate().translationX(0f) + .translationY(0f) + .scaleX(1f) + .scaleY(1f) + .setDuration(200).start() + } + } + + private fun setSingleTouch(value: Boolean) { + mSingleTouch = value + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + animate().cancel() + } + + interface DragListener { + fun onDrag(draggableBigImageView: DraggableBigImageView, fraction: Float) + fun onRelease(draggableBigImageView: DraggableBigImageView, scale: Float) + fun onRestore(draggableBigImageView: DraggableBigImageView, fraction: Float) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/ImageViewerActivity.kt b/app/src/main/java/com/gh/gamecenter/ImageViewerActivity.kt new file mode 100644 index 0000000000..8c5033d337 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/ImageViewerActivity.kt @@ -0,0 +1,631 @@ +package com.gh.gamecenter + +import android.animation.AnimatorSet +import android.animation.ValueAnimator +import android.annotation.SuppressLint +import android.app.Activity +import android.app.Dialog +import android.content.Context +import android.content.Intent +import android.graphics.BitmapFactory +import android.graphics.Color +import android.net.Uri +import android.os.Bundle +import android.os.Environment +import android.text.TextUtils +import android.util.Base64 +import android.util.DisplayMetrics +import android.view.View +import android.view.ViewGroup +import android.view.ViewTreeObserver.OnGlobalLayoutListener +import android.view.Window +import android.widget.LinearLayout +import android.widget.RelativeLayout +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager.OnPageChangeListener +import butterknife.BindView +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.DefaultOnImageEventListener +import com.facebook.drawee.backends.pipeline.Fresco +import com.facebook.imagepipeline.core.ImagePipeline +import com.facebook.imagepipeline.request.ImageRequest +import com.gh.base.BaseActivity +import com.gh.common.Base64ImageHolder.image +import com.gh.common.runOnIoThread +import com.gh.common.util.* +import com.gh.common.util.ImageUtils.getTransformLimitUrl +import com.gh.common.view.DraggableBigImageView +import com.gh.common.view.Gh_RelativeLayout +import com.gh.common.view.Gh_ViewPager +import com.gh.gamecenter.entity.ImageInfoEntity +import com.gh.gamecenter.retrofit.Response +import com.gh.gamecenter.retrofit.RetrofitManager +import com.github.piasy.biv.view.BigImageView +import com.github.piasy.biv.view.FrescoImageViewFactory +import com.lightgame.utils.Utils +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import java.io.* +import java.util.* + +/** + * 查看游戏截图页面 + * + * @author 黄壮华 + * + * todo BigImageView静态webp/动态webp(ImageInfoExtractor.getImageType(image))判断有问题,导致部分静态webp无法使用缩放功能 + */ +class ImageViewerActivity : BaseActivity(), OnPageChangeListener { + + @BindView(R.id.image_detail_page) + lateinit var mViewPager: Gh_ViewPager + + @BindView(R.id.image_detail_progress) + lateinit var mProgressHint: TextView + + @BindView(R.id.image_mask) + lateinit var mIndicatorMask: View + + @BindView(R.id.image_indicator_tv) + lateinit var mIndicatorTv: TextView + + @BindView(R.id.background_view) + lateinit var mBackgroundView: View + + private var adapter: ViewImageAdapter? = null + private var mImagePipeline: ImagePipeline? = null + private var mShowBase64Image = false + private var mUrlList: ArrayList? = null + private var mViewedSet: HashSet? = null // 让调用者知道该图片是否被看过了 + private var mImageInfoMap: MutableMap? = null + private var mBigImageView: BigImageView? = null + + private var mInitialPosition = 0 + private var mUseEnterAndExitAnimation = false + + private var mLimitWidth = 0 + private var mOriginLeft = 0 + private var mOriginTop = 0 + private var mOriginHeight = 0 + private var mOriginWidth = 0 + private var mOriginCenterX = 0 + private var mOriginCenterY = 0 + private var mOriginHeightWidthRatio = 0f + private var mTargetHeight = 0f + private var mTargetWidth = 0f + private var mScaleX = 0f + private var mScaleY = 0f + private var mTranslationX = 0f + private var mTranslationY = 0f + + override fun getLayoutId() = R.layout.activity_viewimage + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + mViewedSet = HashSet() + mImageInfoMap = HashMap() + mImagePipeline = Fresco.getImagePipeline() + + mInitialPosition = savedInstanceState?.getInt(EntranceUtils.KEY_CURRENTITEM, 0) ?: 0 + + intent.extras?.let { + if (it.getBoolean(KEY_BASE64)) { + mShowBase64Image = true + mUrlList = ArrayList() + mUrlList?.add(image) + } else { + mUrlList = it.getStringArrayList(KEY_URL_LIST) + mInitialPosition = it.getInt(KEY_CURRENT, 0) + } + mUseEnterAndExitAnimation = it.getBoolean(KEY_USE_ENTER_AND_EXIT_ANIMATION) + } + mIndicatorMask.goneIf(mUrlList?.size == 1) + mIndicatorTv.text = String.format("%d/%d", mInitialPosition + 1, mUrlList!!.size) + + // init slide + val outMetrics = DisplayMetrics() + windowManager.defaultDisplay.getMetrics(outMetrics) + val widthPixels = outMetrics.widthPixels + mLimitWidth = if (NetworkUtils.isWifiOr4GConnected(this)) { + widthPixels * 2 + } else { + widthPixels + } + // init viewPage + adapter = ViewImageAdapter() + mViewPager.adapter = adapter + mViewPager.currentItem = mInitialPosition + mViewPager.addOnPageChangeListener(this) + mProgressHint.setOnClickListener { + val position = mViewPager.currentItem + val `object`: Any? = mViewPager.findViewWithTag(position) + if (`object` != null) { + mProgressHint.width = mProgressHint.width + val view = `object` as RelativeLayout + val imageView: BigImageView = view.findViewById(R.id.viewimage_iv_show) + val url = mUrlList!![position] + imageView.showImage(Uri.parse(url)) + imageView.setImageLoaderCallback(object : SimpleImageLoader() { + @SuppressLint("SetTextI18n") + override fun onProgress(progress: Int) { + if (position == mViewPager.currentItem) { // 防止下载过程中切换图片 + if (progress < 100) { + mProgressHint.text = "$progress%" + } else { + mProgressHint.text = "已完成" + mBaseHandler.postDelayed({ + if (position == mViewPager.currentItem) { // 防止等待过程中切换图片 + mProgressHint.visibility = View.GONE + } + }, 500) + } + } + } + }) + } + } + + initEnterAnimation() + DisplayUtils.transparentStatusAndNavigation(this) + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putInt(EntranceUtils.KEY_CURRENTITEM, mViewPager.currentItem) + } + + override fun onDestroy() { + super.onDestroy() + if (mShowBase64Image) { + mUrlList!!.clear() + image = "" + } + mViewPager.onDestroy() // 注销EventBus + } + + @SuppressLint("SetTextI18n") + override fun onPageScrolled(position: Int, positionOffset: Float, + positionOffsetPixels: Int) { + if (positionOffset != 0f) { + mProgressHint.visibility = View.GONE + } else { + val url = mUrlList!![position] + val imageInfoEntity = mImageInfoMap!![url] + if (imageInfoEntity?.fileSize != null && + !mImagePipeline!!.isInBitmapMemoryCache(ImageRequest.fromUri(url)) && + !mImagePipeline!!.isInDiskCacheSync(ImageRequest.fromUri(url))) { + val size = String.format(Locale.CHINA, "%.1fM", + Integer.valueOf(imageInfoEntity.fileSize.value) / 1024f / 1024f) + mProgressHint.visibility = View.VISIBLE + mProgressHint.text = "查看原图($size)" + val layoutParams = mProgressHint.layoutParams + layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT + mProgressHint.layoutParams = layoutParams + } + } + mViewedSet?.add(position) + setResult(Activity.RESULT_OK, Intent().putExtra(VIEWED_IMAGE, mViewedSet)) + } + + override fun onPageSelected(position: Int) { + var ghRelativeLayout: Gh_RelativeLayout? + for (i in 0 until mViewPager.childCount) { + if (mViewPager.getChildAt(i).tag != null) { + ghRelativeLayout = mViewPager.getChildAt(i) as? Gh_RelativeLayout + if (ghRelativeLayout == null) { + return + } + val imageView: BigImageView = ghRelativeLayout.findViewById(R.id.viewimage_iv_show) + val ssiv = imageView.ssiv + ssiv?.resetScaleAndCenter() + } + } + mIndicatorTv.text = String.format("%d/%d", position + 1, mUrlList!!.size) + } + + override fun onPageScrollStateChanged(newState: Int) {} + + private fun initEnterAnimation() { + mViewPager.viewTreeObserver + .addOnGlobalLayoutListener(object : OnGlobalLayoutListener { + override fun onGlobalLayout() { + mViewPager.viewTreeObserver.removeOnGlobalLayoutListener(this) + mOriginLeft = intent.getIntExtra(KEY_LEFT, 0) + mOriginTop = intent.getIntExtra(KEY_TOP, 0) + mOriginHeight = intent.getIntExtra(KEY_HEIGHT, 0) + mOriginWidth = intent.getIntExtra(KEY_WIDTH, 0) + mOriginCenterX = mOriginLeft + mOriginWidth / 2 + mOriginCenterY = mOriginTop + mOriginHeight / 2 + mOriginHeightWidthRatio = mOriginHeight.toFloat() / mOriginWidth + val location = IntArray(2) + mBigImageView?.getLocationOnScreen(location) + mTargetHeight = mBigImageView?.height?.toFloat() ?: 0F + mTargetWidth = mBigImageView?.width?.toFloat() ?: 0F + mScaleX = mOriginWidth.toFloat() / mTargetWidth + // TODO 非等比例缩放的图片需要动画不正常 + mScaleY = mScaleX + val targetCenterX = location[0] + mTargetWidth / 2 + val targetCenterY = location[1] + mTargetHeight / 2 + mTranslationX = mOriginCenterX - targetCenterX + mTranslationY = mOriginCenterY - targetCenterY + + if (mUseEnterAndExitAnimation) { + mBigImageView?.translationX = mTranslationX + mBigImageView?.translationY = mTranslationY + mBigImageView?.scaleX = mScaleX + mBigImageView?.scaleY = mScaleY + } + + performEnterAnimation() + } + }) + } + + private fun loadImageInfo(position: Int, width: Int) { + val url = mUrlList!![position] + RetrofitManager.getInstance(this) + .api.getImageInfo("$url?x-oss-process=image/info") + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : Response() { + override fun onResponse(response: ImageInfoEntity?) { + if (response?.imageWidth != null && Integer.valueOf(response.imageWidth.value) > width) { + mImageInfoMap!![url] = response + if (position == mViewPager.currentItem) { + onPageScrolled(position, 0f, 0) // 刷新下载原图提示按钮 + } + } + } + }) + } + + private fun loadImage(originalUrl: String, decoratedUrl: String?, imageView: BigImageView) { + if (TextUtils.isEmpty(originalUrl)) return + if (originalUrl.startsWith("data:image/png;base64")) { + runOnIoThread { + val base64String = originalUrl.replace("data:image/png;base64", "") + try { + val imageFile = File(cacheDir.absolutePath + File.separator + System.currentTimeMillis() + ".png") + val decodedString = Base64.decode(base64String, Base64.DEFAULT) + val bos = BufferedOutputStream(FileOutputStream(imageFile)) + bos.write(decodedString) + bos.flush() + bos.close() + runOnUiThread { + imageView.setImageViewFactory(FrescoImageViewFactory()) + imageView.showImage(Uri.fromFile(imageFile)) + } + } catch (e: Exception) { + e.printStackTrace() + } + } + } else { + // 添加GIF支持 + imageView.setImageViewFactory(FrescoImageViewFactory()) + // TODO 预览图 scaleType 与最终图不一样,会出现闪一下的问题 + imageView.showImage(Uri.parse(originalUrl), Uri.parse(decoratedUrl)) + } + } + + private fun finishWithAnimation() { + val animatorSet = AnimatorSet() + + val translateXAnimator = ValueAnimator.ofFloat(0F, mTranslationX).apply { + addUpdateListener { va -> mBigImageView?.x = (va.animatedValue as Float) } + } + val translateYAnimator = ValueAnimator.ofFloat(0F, mTranslationY).apply { + addUpdateListener { va -> mBigImageView?.y = (va.animatedValue as Float) } + } + val scaleYAnimator = ValueAnimator.ofFloat(1F, mScaleY).apply { + addUpdateListener { va -> mBigImageView?.scaleY = (va.animatedValue as Float) } + } + val scaleXAnimator = ValueAnimator.ofFloat(1F, mScaleX).apply { + addUpdateListener { va -> mBigImageView?.scaleX = (va.animatedValue as Float) } + } + val backgroundAlphaAnimation = ValueAnimator.ofFloat(1F, 0F).apply { + addUpdateListener { va -> mBackgroundView.alpha = (va.animatedValue as Float) } + } + val alphaAnimator = ValueAnimator.ofFloat(1F, 0F).apply { + addUpdateListener { va -> mBigImageView?.ssiv?.alpha = (va.animatedValue as Float) } + } + + animatorSet.apply { + if (mUseEnterAndExitAnimation) { + playTogether(translateXAnimator, translateYAnimator, scaleXAnimator, scaleYAnimator, backgroundAlphaAnimation) + } else { + playTogether(alphaAnimator, backgroundAlphaAnimation) + } + duration = ANIMATION_DURATION + doOnStart { mIndicatorMask.visibility = View.GONE } + doOnEnd { + it.removeAllListeners() + finish() + overridePendingTransition(0, 0) + } + }.start() + } + + private fun performEnterAnimation() { + val animatorSet = AnimatorSet() + + val translateXAnimator = ValueAnimator.ofFloat(mBigImageView!!.x, 0F).apply { + addUpdateListener { va -> mBigImageView?.x = (va.animatedValue as Float) } + } + val translateYAnimator = ValueAnimator.ofFloat(mBigImageView!!.y, 0F).apply { + addUpdateListener { va -> mBigImageView?.y = (va.animatedValue as Float) } + } + val scaleYAnimator = ValueAnimator.ofFloat(mScaleY, 1F).apply { + addUpdateListener { va -> mBigImageView?.scaleY = (va.animatedValue as Float) } + } + val scaleXAnimator = ValueAnimator.ofFloat(mScaleX, 1F).apply { + addUpdateListener { va -> mBigImageView?.scaleX = (va.animatedValue as Float) } + } + val backgroundAlphaAnimator = ValueAnimator.ofFloat(0F, 1F).apply { + addUpdateListener { va -> mBackgroundView.alpha = (va.animatedValue as Float) } + } + + animatorSet.apply { + if (mUseEnterAndExitAnimation) { + playTogether(translateXAnimator, translateYAnimator, scaleXAnimator, scaleYAnimator, backgroundAlphaAnimator) + } else { + playTogether(backgroundAlphaAnimator) + } + duration = ANIMATION_DURATION + doOnStart { mIndicatorMask.visibility = View.GONE } + doOnEnd { + if (mUrlList?.size != 1) { + mIndicatorMask.visibility = View.VISIBLE + } + } + }.start() + } + + private fun performExitAnimation(view: DraggableBigImageView, scale: Float, fadeOnly: Boolean) { + val finalScale = mOriginWidth / mTargetWidth + val finalTranslationX = mOriginLeft - (1 - finalScale) * mTargetWidth / 2 + // TODO 不知道下面这 4dp 从何而来,但就缺了 4dp + val finalTranslationY = mOriginTop - DisplayUtils.getStatusBarHeight(this.resources) - DisplayUtils.dip2px(4f) - (1 - finalScale) * mTargetHeight / 2 + + val animatorSet = AnimatorSet() + + val scaleAnimator = ValueAnimator.ofFloat(scale, finalScale).apply { + addUpdateListener { va -> + view.scaleX = (va.animatedValue as Float) + view.scaleY = (va.animatedValue as Float) + } + } + val translateXAnimator = ValueAnimator.ofFloat(view.x, finalTranslationX).apply { + addUpdateListener { va -> view.translationX = (va.animatedValue as Float) } + } + val translateYAnimator = ValueAnimator.ofFloat(view.y, finalTranslationY).apply { + addUpdateListener { va -> view.translationY = (va.animatedValue as Float) } + } + val backgroundAlphaAnimator = ValueAnimator.ofFloat(mBackgroundView.alpha, 0F).apply { + addUpdateListener { va -> mBackgroundView.alpha = (va.animatedValue as Float) } + } + val alphaAnimator = ValueAnimator.ofFloat(1F, 0F).apply { + addUpdateListener { va -> view.alpha = (va.animatedValue as Float) } + } + + animatorSet.apply { + if (mUseEnterAndExitAnimation && !fadeOnly) { + playTogether(scaleAnimator, translateXAnimator, translateYAnimator, backgroundAlphaAnimator) + } else { + playTogether(backgroundAlphaAnimator, alphaAnimator) + } + doOnEnd { + it.removeAllListeners() + finish() + overridePendingTransition(0, 0) + } + duration = ANIMATION_DURATION + }.start() + } + + private inner class ViewImageAdapter : PagerAdapter() { + override fun getCount() = mUrlList?.size ?: 0 + + @SuppressLint("MissingPermission") + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val originalUrl = mUrlList!![position] + var decoratedUrl: String? = originalUrl + val imageRequest = ImageRequest.fromUri(originalUrl) + val isInMemoryCache = mImagePipeline!!.isInBitmapMemoryCache(imageRequest) + val isInDiskCache = imageRequest != null && mImagePipeline!!.isInDiskCacheSync(imageRequest) + val view = View.inflate(container.context, R.layout.viewimage_normal_item, null) as Gh_RelativeLayout + val imageView: DraggableBigImageView = view.findViewById(R.id.viewimage_iv_show) + if (mBigImageView == null) { + mBigImageView = imageView + } + imageView.setDragListener(object : DraggableBigImageView.DragListener { + override fun onRelease(draggableBigImageView: DraggableBigImageView, scale: Float) { + performExitAnimation(draggableBigImageView, scale, mViewPager.currentItem != mInitialPosition) + } + + override fun onDrag(draggableBigImageView: DraggableBigImageView, fraction: Float) { + mBackgroundView.alpha = 1 - fraction + mIndicatorMask.visibility = View.GONE + } + + override fun onRestore(draggableBigImageView: DraggableBigImageView, fraction: Float) { + mBackgroundView.alpha = 1F + mIndicatorMask.goneIf(mUrlList?.size == 1) + } + }) + if (!isInMemoryCache + && !isInDiskCache + && !NetworkUtils.isWifiOr4GConnected(this@ImageViewerActivity) + && !originalUrl.contains(".gif")) { + decoratedUrl = getTransformLimitUrl(originalUrl, mLimitWidth, applicationContext) + } + val finalUrl = decoratedUrl + imageView.setImageLoaderCallback(object : SimpleImageLoader() { + override fun onSuccess(image: File) { + if (finalUrl != mUrlList!![position]) { + val options = BitmapFactory.Options() + options.inJustDecodeBounds = true + BitmapFactory.decodeFile(File(image.path).absolutePath, options) + loadImageInfo(position, options.outWidth) // 加载图片参数,目的是用户显示原文按钮 + } + val ssiv = imageView.ssiv + if (ssiv != null) { + ssiv.maxScale = 10f // 这个缩放倍数最好很具宽高自动调节 + ssiv.setOnImageEventListener(object : DefaultOnImageEventListener() { + override fun onReady() { + ssiv.resetScaleAndCenter() + } + }) + ssiv.setOnClickListener { finishWithAnimation() } + } + } + }) + loadImage(originalUrl, decoratedUrl, imageView) + + //长按 + imageView.setOnLongClickListener { + val dialog = Dialog(this@ImageViewerActivity) + val container1 = LinearLayout(this@ImageViewerActivity) + container1.orientation = LinearLayout.VERTICAL + container1.setBackgroundColor(Color.WHITE) + val reportTv = TextView(this@ImageViewerActivity) + reportTv.setPadding( + DisplayUtils.dip2px(this@ImageViewerActivity, 20f), + DisplayUtils.dip2px(this@ImageViewerActivity, 12f), + 0, + DisplayUtils.dip2px(this@ImageViewerActivity, 12f)) + reportTv.setText(R.string.save_pic) + reportTv.textSize = 17f + reportTv.setTextColor(ContextCompat.getColor(applicationContext, R.color.title)) + reportTv.setBackgroundResource(R.drawable.textview_white_style) + val widthPixels = resources.displayMetrics.widthPixels + reportTv.layoutParams = LinearLayout.LayoutParams(widthPixels * 9 / 10, + LinearLayout.LayoutParams.WRAP_CONTENT) + container1.addView(reportTv) + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE) + dialog.setContentView(container1) + if (!isFinishing) { + dialog.show() + } + reportTv.setOnClickListener { + checkStoragePermissionBeforeAction { + saveImageToFile(imageView.currentImageFile, finalUrl) + dialog.cancel() + } + dialog.cancel() + } + false + } + view.tag = position + container.addView(view) + return view + } + + private fun saveImageToFile(src: File, curUrl: String?) { + var `in`: InputStream? = null + var out: OutputStream? = null + try { + val fileName: String = if (mShowBase64Image) { + MD5Utils.getUrlMD5(curUrl!!.substring(0, 50)) + ".png" + } else { + curUrl!!.substring(curUrl.lastIndexOf("/")) + } + val savePath = Environment.getExternalStorageDirectory().absolutePath + "/Pictures/ghzhushou/" + val file = File(savePath) + if (!file.exists()) { + file.mkdirs() + } + val dst = File(savePath, fileName) + if (dst.exists()) { + dst.delete() + } + `in` = FileInputStream(src) + out = FileOutputStream(dst) + val buf = ByteArray(1024) + var len: Int + while (`in`.read(buf).also { len = it } > 0) { + out.write(buf, 0, len) + } + Utils.toast(this@ImageViewerActivity, "图片已保存到/Pictures/ghzhushou/") + MessageShareUtils.refreshImage(this@ImageViewerActivity, dst) + } catch (e: Exception) { + Utils.log("图片保存失败:$e") + } finally { + try { + out?.close() + `in`?.close() + } catch (ignore: Exception) { + } + } + } + + override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) { + container.removeView(`object` as View) + } + + override fun isViewFromObject(view: View, `object`: Any): Boolean { + return view === `object` + } + } + + override fun onBackPressed() { + finishWithAnimation() + } + + companion object { + const val REQUEST_FOR_VIEWED_IMAGE = 921 + const val VIEWED_IMAGE = "viewed_image" + + private const val KEY_BASE64 = "base64" + private const val KEY_URL_LIST = "urls" + private const val KEY_CURRENT = "current" + private const val KEY_USE_ENTER_AND_EXIT_ANIMATION = "use_enter_and_exit_animation" + + private const val KEY_LEFT = "left" + private const val KEY_TOP = "top" + private const val KEY_HEIGHT = "height" + private const val KEY_WIDTH = "width" + + private const val ANIMATION_DURATION = 300L + + @JvmStatic + fun getBase64Intent(context: Context?, showSingleBase64Image: Boolean): Intent { + val checkIntent = Intent(context, ImageViewerActivity::class.java) + checkIntent.putExtra(KEY_BASE64, showSingleBase64Image) + return checkIntent + } + + @JvmStatic + fun getIntent(context: Context, list: ArrayList, position: Int = 0, entrance: String?): Intent { + return getIntent(context, list, position, null, entrance) + } + + /** + * 传入 view 代表使用渐入渐出动画 + */ + @JvmStatic + fun getIntent(context: Context, list: ArrayList, position: Int = 0, originalView: View? = null, entrance: String?): Intent { + val intent = Intent(context, ImageViewerActivity::class.java) + intent.putExtra(KEY_URL_LIST, list) + intent.putExtra(KEY_CURRENT, position) + intent.putExtra(EntranceUtils.KEY_ENTRANCE, entrance) + + val location = IntArray(2) + if (originalView != null) { + originalView.getLocationOnScreen(location) + intent.putExtra(KEY_LEFT, location[0]) + intent.putExtra(KEY_TOP, location[1]) + intent.putExtra(KEY_HEIGHT, originalView.height) + intent.putExtra(KEY_WIDTH, originalView.width) + intent.putExtra(KEY_USE_ENTER_AND_EXIT_ANIMATION, true) + } + + if (context is Activity) { + context.overridePendingTransition(0, 0) + } + + return intent + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java b/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java index 54e17f6e11..f723012272 100644 --- a/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java +++ b/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java @@ -18,6 +18,10 @@ import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.core.view.MotionEventCompat; +import androidx.recyclerview.widget.RecyclerView; + import com.ethanhua.skeleton.Skeleton; import com.ethanhua.skeleton.ViewSkeletonScreen; import com.gh.base.OnRequestCallBackListener; @@ -65,9 +69,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; -import androidx.annotation.NonNull; -import androidx.core.view.MotionEventCompat; -import androidx.recyclerview.widget.RecyclerView; import butterknife.BindView; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; @@ -228,8 +229,8 @@ public class NewsDetailActivity extends ToolBarActivity implements OnClickListen @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == ViewImageActivity.REQUEST_FOR_VIEWED_IMAGE && resultCode == Activity.RESULT_OK) { - HashSet imageSet = (HashSet) data.getExtras().get(ViewImageActivity.VIEWED_IMAGE); + if (requestCode == ImageViewerActivity.REQUEST_FOR_VIEWED_IMAGE && resultCode == Activity.RESULT_OK) { + HashSet imageSet = (HashSet) data.getExtras().get(ImageViewerActivity.VIEWED_IMAGE); adapter.replaceDefaultImage(imageSet); } } diff --git a/app/src/main/java/com/gh/gamecenter/ViewImageActivity.java b/app/src/main/java/com/gh/gamecenter/ViewImageActivity.java index 598f5922a2..431bee1b14 100644 --- a/app/src/main/java/com/gh/gamecenter/ViewImageActivity.java +++ b/app/src/main/java/com/gh/gamecenter/ViewImageActivity.java @@ -1,482 +1,482 @@ -package com.gh.gamecenter; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.Dialog; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.graphics.BitmapFactory; -import android.graphics.Color; -import android.net.Uri; -import android.os.Bundle; -import android.os.Environment; -import android.text.TextUtils; -import android.util.Base64; -import android.util.DisplayMetrics; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import androidx.viewpager.widget.PagerAdapter; -import androidx.viewpager.widget.ViewPager.OnPageChangeListener; - -import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; -import com.facebook.drawee.backends.pipeline.Fresco; -import com.facebook.imagepipeline.core.ImagePipeline; -import com.facebook.imagepipeline.request.ImageRequest; -import com.gh.base.BaseActivity; -import com.gh.common.AppExecutor; -import com.gh.common.Base64ImageHolder; -import com.gh.common.util.DisplayUtils; -import com.gh.common.util.EntranceUtils; -import com.gh.common.util.ImageUtils; -import com.gh.common.util.MD5Utils; -import com.gh.common.util.MessageShareUtils; -import com.gh.common.util.NetworkUtils; -import com.gh.common.util.PermissionHelper; -import com.gh.common.util.SimpleImageLoader; -import com.gh.common.view.Gh_RelativeLayout; -import com.gh.common.view.Gh_ViewPager; -import com.gh.gamecenter.entity.ImageInfoEntity; -import com.gh.gamecenter.retrofit.Response; -import com.gh.gamecenter.retrofit.RetrofitManager; -import com.github.piasy.biv.view.BigImageView; -import com.github.piasy.biv.view.FrescoImageViewFactory; -import com.lightgame.utils.Utils; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Locale; -import java.util.Map; - -import butterknife.BindView; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.schedulers.Schedulers; - -/** - * 查看游戏截图页面 - * - * @author 黄壮华 - * - * todo BigImageView静态webp/动态webp(ImageInfoExtractor.getImageType(image))判断有问题,导致部分静态webp无法使用缩放功能 - */ -public class ViewImageActivity extends BaseActivity implements OnPageChangeListener { - - public static final int REQUEST_FOR_VIEWED_IMAGE = 921; - public static final String VIEWED_IMAGE = "viewed_image"; - - @BindView(R.id.image_detail_page) - Gh_ViewPager mViewPager; - @BindView(R.id.image_detail_progress) - TextView mProgressHint; - @BindView(R.id.image_mask) - View mIndicatorMask; - @BindView(R.id.image_indicator_tv) - TextView mIndicatorTv; - - private ViewImageAdapter adapter; - - private ImagePipeline mImagePipeline; - - private boolean mShowBase64Image = false; - - private static final String KEY_BASE64 = "base64"; - - private static final String KEY_URLS = "urls"; - private static final String KEY_CURRENT = "current"; - - private ArrayList urls; - private HashSet mViewedSet; // 让调用者知道该图片是否被看过了 - private Map mImageInfoMap; - - private int mLimitWidth; - - private boolean isOrientation; - - public static Intent getBase64ViewImageIntent(Context context, boolean showSingleBase64Image) { - Intent checkIntent = new Intent(context, ViewImageActivity.class); - checkIntent.putExtra(KEY_BASE64, showSingleBase64Image); - return checkIntent; - } - - public static Intent getViewImageIntent(Context context, ArrayList list, int position, String entrance) { - Intent checkIntent = new Intent(context, ViewImageActivity.class); - checkIntent.putExtra(KEY_URLS, list); - checkIntent.putExtra(KEY_CURRENT, position); - checkIntent.putExtra(EntranceUtils.KEY_ENTRANCE, entrance); - return checkIntent; - } - - @Override - protected int getLayoutId() { - return R.layout.activity_viewimage; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mViewedSet = new HashSet<>(); - mImageInfoMap = new HashMap<>(); - // init data - int current = 0; - Bundle extras = getIntent().getExtras(); - if (extras != null) { - if (extras.getBoolean(KEY_BASE64)) { - mShowBase64Image = true; - urls = new ArrayList<>(); - urls.add(Base64ImageHolder.INSTANCE.getImage()); - } else { - urls = extras.getStringArrayList(KEY_URLS); - current = extras.getInt(KEY_CURRENT, 0); - } - } - - if (savedInstanceState != null) { - current = savedInstanceState.getInt(EntranceUtils.KEY_CURRENTITEM, 0); - isOrientation = savedInstanceState.getBoolean("isOrientation"); - } - - if (urls.size() > 1) mIndicatorMask.setVisibility(View.VISIBLE); - mIndicatorTv.setText(String.format("%d/%d", current + 1, urls.size())); - - mImagePipeline = Fresco.getImagePipeline(); - - // init slide - DisplayMetrics outMetrics = new DisplayMetrics(); - getWindowManager().getDefaultDisplay().getMetrics(outMetrics); - int widthPixels = outMetrics.widthPixels; - if (NetworkUtils.isWifiOr4GConnected(this)) { - mLimitWidth = widthPixels * 2; - } else { - mLimitWidth = widthPixels; - } - // init viewPage - adapter = new ViewImageAdapter(); - mViewPager.setAdapter(adapter); - mViewPager.setCurrentItem(current); - mViewPager.addOnPageChangeListener(this); - - if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { - isOrientation = true; // 横屏 - } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { - isOrientation = false;// 竖屏 - } - - mProgressHint.setOnClickListener(v -> { - int position = mViewPager.getCurrentItem(); - Object object = mViewPager.findViewWithTag(position); - if (object != null) { - mProgressHint.setWidth(mProgressHint.getWidth()); - RelativeLayout view = (RelativeLayout) object; - final BigImageView imageView = view.findViewById(R.id.viewimage_iv_show); - String url = urls.get(position); - imageView.showImage(Uri.parse(url)); - imageView.setImageLoaderCallback(new SimpleImageLoader() { - @Override - public void onProgress(int progress) { - if (position == mViewPager.getCurrentItem()) { // 防止下载过程中切换图片 - if (progress < 100) { - mProgressHint.setText((progress + "%")); - } else { - mProgressHint.setText("已完成"); - mBaseHandler.postDelayed(() -> { - if (position == mViewPager.getCurrentItem()) { // 防止等待过程中切换图片 - mProgressHint.setVisibility(View.GONE); - } - }, 500); - } - } - } - }); - } - }); - - DisplayUtils.transparentStatusAndNavigation(this); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putInt(EntranceUtils.KEY_CURRENTITEM, mViewPager.getCurrentItem()); - outState.putBoolean("isOrientation", isOrientation); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - if (mShowBase64Image) { - urls.clear(); - Base64ImageHolder.INSTANCE.setImage(""); - } - mViewPager.onDestroy(); // 注销EventBus - } - - @Override - public void onPageScrolled(int position, float positionOffset, - int positionOffsetPixels) { - if (positionOffset != 0) { - mProgressHint.setVisibility(View.GONE); - } else { - String url = urls.get(position); - ImageInfoEntity imageInfoEntity = mImageInfoMap.get(url); - if (imageInfoEntity != null && imageInfoEntity.getFileSize() != null && - !mImagePipeline.isInBitmapMemoryCache(ImageRequest.fromUri(url)) && - !mImagePipeline.isInDiskCacheSync(ImageRequest.fromUri(url))) { - String size = String.format(Locale.CHINA, "%.1fM", - Integer.valueOf(imageInfoEntity.getFileSize().getValue()) / 1024F / 1024F); - mProgressHint.setVisibility(View.VISIBLE); - mProgressHint.setText(("查看原图(" + size + ")")); - ViewGroup.LayoutParams layoutParams = mProgressHint.getLayoutParams(); - layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; - mProgressHint.setLayoutParams(layoutParams); - } - } - - mViewedSet.add(position); - setResult(Activity.RESULT_OK, new Intent().putExtra(VIEWED_IMAGE, mViewedSet)); - } - - @Override - public void onPageSelected(int position) { - Gh_RelativeLayout ghRelativeLayout; - for (int i = 0; i < mViewPager.getChildCount(); i++) { - if (mViewPager.getChildAt(i).getTag() != null) { - ghRelativeLayout = (Gh_RelativeLayout) mViewPager.getChildAt(i); - if (ghRelativeLayout == null) { - return; - } - - BigImageView imageView = ghRelativeLayout.findViewById(R.id.viewimage_iv_show); - SubsamplingScaleImageView ssiv = imageView.getSSIV(); - if (ssiv != null) ssiv.resetScaleAndCenter(); - - } - } - mIndicatorTv.setText(String.format("%d/%d", position + 1, urls.size())); - } - - @Override - public void onPageScrollStateChanged(int newState) { - - } - - private void loadImageInfo(int position, int width) { - String url = urls.get(position); - RetrofitManager.getInstance(this) - .getApi().getImageInfo(url + "?x-oss-process=image/info") - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Response() { - @Override - public void onResponse(@Nullable ImageInfoEntity response) { - if (response != null && response.getImageWidth() != null && - Integer.valueOf(response.getImageWidth().getValue()) > width) { - mImageInfoMap.put(url, response); - if (position == mViewPager.getCurrentItem()) { - onPageScrolled(position, 0, 0); // 刷新下载原图提示按钮 - } - } - } - }); - } - - private void loadImage(String url, final BigImageView imageView) { - if (TextUtils.isEmpty(url)) return; - - if (url.startsWith("data:image/png;base64")) { - AppExecutor.getIoExecutor().execute(() -> { - String base64String = url.replace("data:image/png;base64", ""); - try { - File imageFile = new File(getCacheDir().getAbsolutePath() + File.separator + System.currentTimeMillis() + ".png"); - - byte[] decodedString = Base64.decode(base64String, Base64.DEFAULT); - - BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(imageFile)); - bos.write(decodedString); - bos.flush(); - bos.close(); - - AppExecutor.getUiExecutor().execute(() -> { - imageView.setImageViewFactory(new FrescoImageViewFactory()); - imageView.showImage(Uri.fromFile(imageFile)); - }); - } catch (Exception e) { - e.printStackTrace(); - } - }); - } else { - // 添加GIF支持 - imageView.setImageViewFactory(new FrescoImageViewFactory()); - imageView.showImage(Uri.parse(url)); - } - } - - private class ViewImageAdapter extends PagerAdapter { - - @Override - public int getCount() { - if (urls == null) { - return 0; - } - return urls.size(); - } - - @SuppressLint("MissingPermission") - @NonNull - @Override - public Object instantiateItem(@NonNull ViewGroup container, int position) { - String url = urls.get(position); - ImageRequest imageRequest = ImageRequest.fromUri(url); - boolean isInMemoryCache = mImagePipeline.isInBitmapMemoryCache(imageRequest); - boolean isInDiskCache = imageRequest != null && mImagePipeline.isInDiskCacheSync(imageRequest); - - Gh_RelativeLayout view = (Gh_RelativeLayout) View.inflate(container.getContext(), R.layout.viewimage_normal_item, null); - BigImageView imageView = view.findViewById(R.id.viewimage_iv_show); - - if (!isInMemoryCache - && !isInDiskCache - && !NetworkUtils.isWifiOr4GConnected(ViewImageActivity.this) - && !url.contains(".gif")) { - url = ImageUtils.getTransformLimitUrl(url, mLimitWidth, getApplicationContext()); - } - - String finalUrl = url; - imageView.setImageLoaderCallback(new SimpleImageLoader() { - @Override - public void onSuccess(File image) { - if (!finalUrl.equals(urls.get(position))) { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; - BitmapFactory.decodeFile(new File(image.getPath()).getAbsolutePath(), options); - loadImageInfo(position, options.outWidth); // 加载图片参数,目的是用户显示原文按钮 - } - SubsamplingScaleImageView ssiv = imageView.getSSIV(); - if (ssiv != null) { - ssiv.setMaxScale(10f); // 这个缩放倍数最好很具宽高自动调节 - ssiv.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() { - @Override - public void onReady() { - ssiv.resetScaleAndCenter(); - } - }); - ssiv.setOnClickListener(v -> finish()); - - } - } - }); - loadImage(url, imageView); - - //长按 - imageView.setOnLongClickListener(v -> { - final Dialog dialog = new Dialog(ViewImageActivity.this); - - LinearLayout container1 = new LinearLayout(ViewImageActivity.this); - container1.setOrientation(LinearLayout.VERTICAL); - container1.setBackgroundColor(Color.WHITE); - - final TextView reportTv = new TextView(ViewImageActivity.this); - reportTv.setPadding( - DisplayUtils.dip2px(ViewImageActivity.this, 20), - DisplayUtils.dip2px(ViewImageActivity.this, 12), - 0, - DisplayUtils.dip2px(ViewImageActivity.this, 12)); - reportTv.setText(R.string.save_pic); - reportTv.setTextSize(17); - reportTv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.title)); - reportTv.setBackgroundResource(R.drawable.textview_white_style); - int widthPixels = getResources().getDisplayMetrics().widthPixels; - reportTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10, - LinearLayout.LayoutParams.WRAP_CONTENT)); - container1.addView(reportTv); - - dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); - dialog.setContentView(container1); - - if (!isFinishing()) { - dialog.show(); - } - - reportTv.setOnClickListener(v1 -> { - PermissionHelper.checkStoragePermissionBeforeAction(ViewImageActivity.this, () -> { - saveImageToFile(imageView.getCurrentImageFile(), finalUrl); - dialog.cancel(); - }); - dialog.cancel(); - }); - - return false; - }); - - view.setTag(position); - container.addView(view); - return view; - } - - private void saveImageToFile(File src, String curUrl) { - InputStream in = null; - OutputStream out = null; - try { - String fileName; - if (mShowBase64Image) { - fileName = MD5Utils.getUrlMD5(curUrl.substring(0, 50)) + ".png"; - } else { - fileName = curUrl.substring(curUrl.lastIndexOf("/")); - } - String savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/ghzhushou/"; - File file = new File(savePath); - if (!file.exists()) { - file.mkdirs(); - } - - File dst = new File(savePath, fileName); - if (dst.exists()) { - dst.delete(); - } - - in = new FileInputStream(src); - out = new FileOutputStream(dst); - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - - Utils.toast(ViewImageActivity.this, "图片已保存到/Pictures/ghzhushou/"); - MessageShareUtils.refreshImage(ViewImageActivity.this, dst); - } catch (Exception e) { - Utils.log("图片保存失败:" + e.toString()); - } finally { - try { - if (out != null) out.close(); - if (in != null) in.close(); - } catch (Exception ignore) { - } - } - } - - - @Override - public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { - container.removeView((View) object); - } - - @Override - public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { - return view == object; - } - } -} +//package com.gh.gamecenter; +// +//import android.annotation.SuppressLint; +//import android.app.Activity; +//import android.app.Dialog; +//import android.content.Context; +//import android.content.Intent; +//import android.content.res.Configuration; +//import android.graphics.BitmapFactory; +//import android.graphics.Color; +//import android.net.Uri; +//import android.os.Bundle; +//import android.os.Environment; +//import android.text.TextUtils; +//import android.util.Base64; +//import android.util.DisplayMetrics; +//import android.view.View; +//import android.view.ViewGroup; +//import android.view.Window; +//import android.widget.LinearLayout; +//import android.widget.RelativeLayout; +//import android.widget.TextView; +// +//import androidx.annotation.NonNull; +//import androidx.annotation.Nullable; +//import androidx.core.content.ContextCompat; +//import androidx.viewpager.widget.PagerAdapter; +//import androidx.viewpager.widget.ViewPager.OnPageChangeListener; +// +//import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; +//import com.facebook.drawee.backends.pipeline.Fresco; +//import com.facebook.imagepipeline.core.ImagePipeline; +//import com.facebook.imagepipeline.request.ImageRequest; +//import com.gh.base.BaseActivity; +//import com.gh.common.AppExecutor; +//import com.gh.common.Base64ImageHolder; +//import com.gh.common.util.DisplayUtils; +//import com.gh.common.util.EntranceUtils; +//import com.gh.common.util.ImageUtils; +//import com.gh.common.util.MD5Utils; +//import com.gh.common.util.MessageShareUtils; +//import com.gh.common.util.NetworkUtils; +//import com.gh.common.util.PermissionHelper; +//import com.gh.common.util.SimpleImageLoader; +//import com.gh.common.view.Gh_RelativeLayout; +//import com.gh.common.view.Gh_ViewPager; +//import com.gh.gamecenter.entity.ImageInfoEntity; +//import com.gh.gamecenter.retrofit.Response; +//import com.gh.gamecenter.retrofit.RetrofitManager; +//import com.github.piasy.biv.view.BigImageView; +//import com.github.piasy.biv.view.FrescoImageViewFactory; +//import com.lightgame.utils.Utils; +// +//import java.io.BufferedOutputStream; +//import java.io.File; +//import java.io.FileInputStream; +//import java.io.FileOutputStream; +//import java.io.InputStream; +//import java.io.OutputStream; +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.HashSet; +//import java.util.Locale; +//import java.util.Map; +// +//import butterknife.BindView; +//import io.reactivex.android.schedulers.AndroidSchedulers; +//import io.reactivex.schedulers.Schedulers; +// +///** +// * 查看游戏截图页面 +// * +// * @author 黄壮华 +// * +// * todo BigImageView静态webp/动态webp(ImageInfoExtractor.getImageType(image))判断有问题,导致部分静态webp无法使用缩放功能 +// */ +//public class ViewImageActivity extends BaseActivity implements OnPageChangeListener { +// +// public static final int REQUEST_FOR_VIEWED_IMAGE = 921; +// public static final String VIEWED_IMAGE = "viewed_image"; +// +// @BindView(R.id.image_detail_page) +// Gh_ViewPager mViewPager; +// @BindView(R.id.image_detail_progress) +// TextView mProgressHint; +// @BindView(R.id.image_mask) +// View mIndicatorMask; +// @BindView(R.id.image_indicator_tv) +// TextView mIndicatorTv; +// +// private ViewImageAdapter adapter; +// +// private ImagePipeline mImagePipeline; +// +// private boolean mShowBase64Image = false; +// +// private static final String KEY_BASE64 = "base64"; +// +// private static final String KEY_URLS = "urls"; +// private static final String KEY_CURRENT = "current"; +// +// private ArrayList urls; +// private HashSet mViewedSet; // 让调用者知道该图片是否被看过了 +// private Map mImageInfoMap; +// +// private int mLimitWidth; +// +// private boolean isOrientation; +// +// public static Intent getBase64ViewImageIntent(Context context, boolean showSingleBase64Image) { +// Intent checkIntent = new Intent(context, ViewImageActivity.class); +// checkIntent.putExtra(KEY_BASE64, showSingleBase64Image); +// return checkIntent; +// } +// +// public static Intent getViewImageIntent(Context context, ArrayList list, int position, String entrance) { +// Intent checkIntent = new Intent(context, ViewImageActivity.class); +// checkIntent.putExtra(KEY_URLS, list); +// checkIntent.putExtra(KEY_CURRENT, position); +// checkIntent.putExtra(EntranceUtils.KEY_ENTRANCE, entrance); +// return checkIntent; +// } +// +// @Override +// protected int getLayoutId() { +// return R.layout.activity_viewimage; +// } +// +// @Override +// protected void onCreate(Bundle savedInstanceState) { +// super.onCreate(savedInstanceState); +// mViewedSet = new HashSet<>(); +// mImageInfoMap = new HashMap<>(); +// // init data +// int current = 0; +// Bundle extras = getIntent().getExtras(); +// if (extras != null) { +// if (extras.getBoolean(KEY_BASE64)) { +// mShowBase64Image = true; +// urls = new ArrayList<>(); +// urls.add(Base64ImageHolder.INSTANCE.getImage()); +// } else { +// urls = extras.getStringArrayList(KEY_URLS); +// current = extras.getInt(KEY_CURRENT, 0); +// } +// } +// +// if (savedInstanceState != null) { +// current = savedInstanceState.getInt(EntranceUtils.KEY_CURRENTITEM, 0); +// isOrientation = savedInstanceState.getBoolean("isOrientation"); +// } +// +// if (urls.size() > 1) mIndicatorMask.setVisibility(View.VISIBLE); +// mIndicatorTv.setText(String.format("%d/%d", current + 1, urls.size())); +// +// mImagePipeline = Fresco.getImagePipeline(); +// +// // init slide +// DisplayMetrics outMetrics = new DisplayMetrics(); +// getWindowManager().getDefaultDisplay().getMetrics(outMetrics); +// int widthPixels = outMetrics.widthPixels; +// if (NetworkUtils.isWifiOr4GConnected(this)) { +// mLimitWidth = widthPixels * 2; +// } else { +// mLimitWidth = widthPixels; +// } +// // init viewPage +// adapter = new ViewImageAdapter(); +// mViewPager.setAdapter(adapter); +// mViewPager.setCurrentItem(current); +// mViewPager.addOnPageChangeListener(this); +// +// if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { +// isOrientation = true; // 横屏 +// } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { +// isOrientation = false;// 竖屏 +// } +// +// mProgressHint.setOnClickListener(v -> { +// int position = mViewPager.getCurrentItem(); +// Object object = mViewPager.findViewWithTag(position); +// if (object != null) { +// mProgressHint.setWidth(mProgressHint.getWidth()); +// RelativeLayout view = (RelativeLayout) object; +// final BigImageView imageView = view.findViewById(R.id.viewimage_iv_show); +// String url = urls.get(position); +// imageView.showImage(Uri.parse(url)); +// imageView.setImageLoaderCallback(new SimpleImageLoader() { +// @Override +// public void onProgress(int progress) { +// if (position == mViewPager.getCurrentItem()) { // 防止下载过程中切换图片 +// if (progress < 100) { +// mProgressHint.setText((progress + "%")); +// } else { +// mProgressHint.setText("已完成"); +// mBaseHandler.postDelayed(() -> { +// if (position == mViewPager.getCurrentItem()) { // 防止等待过程中切换图片 +// mProgressHint.setVisibility(View.GONE); +// } +// }, 500); +// } +// } +// } +// }); +// } +// }); +// +// DisplayUtils.transparentStatusAndNavigation(this); +// } +// +// @Override +// protected void onSaveInstanceState(Bundle outState) { +// super.onSaveInstanceState(outState); +// outState.putInt(EntranceUtils.KEY_CURRENTITEM, mViewPager.getCurrentItem()); +// outState.putBoolean("isOrientation", isOrientation); +// } +// +// @Override +// protected void onDestroy() { +// super.onDestroy(); +// if (mShowBase64Image) { +// urls.clear(); +// Base64ImageHolder.INSTANCE.setImage(""); +// } +// mViewPager.onDestroy(); // 注销EventBus +// } +// +// @Override +// public void onPageScrolled(int position, float positionOffset, +// int positionOffsetPixels) { +// if (positionOffset != 0) { +// mProgressHint.setVisibility(View.GONE); +// } else { +// String url = urls.get(position); +// ImageInfoEntity imageInfoEntity = mImageInfoMap.get(url); +// if (imageInfoEntity != null && imageInfoEntity.getFileSize() != null && +// !mImagePipeline.isInBitmapMemoryCache(ImageRequest.fromUri(url)) && +// !mImagePipeline.isInDiskCacheSync(ImageRequest.fromUri(url))) { +// String size = String.format(Locale.CHINA, "%.1fM", +// Integer.valueOf(imageInfoEntity.getFileSize().getValue()) / 1024F / 1024F); +// mProgressHint.setVisibility(View.VISIBLE); +// mProgressHint.setText(("查看原图(" + size + ")")); +// ViewGroup.LayoutParams layoutParams = mProgressHint.getLayoutParams(); +// layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; +// mProgressHint.setLayoutParams(layoutParams); +// } +// } +// +// mViewedSet.add(position); +// setResult(Activity.RESULT_OK, new Intent().putExtra(VIEWED_IMAGE, mViewedSet)); +// } +// +// @Override +// public void onPageSelected(int position) { +// Gh_RelativeLayout ghRelativeLayout; +// for (int i = 0; i < mViewPager.getChildCount(); i++) { +// if (mViewPager.getChildAt(i).getTag() != null) { +// ghRelativeLayout = (Gh_RelativeLayout) mViewPager.getChildAt(i); +// if (ghRelativeLayout == null) { +// return; +// } +// +// BigImageView imageView = ghRelativeLayout.findViewById(R.id.viewimage_iv_show); +// SubsamplingScaleImageView ssiv = imageView.getSSIV(); +// if (ssiv != null) ssiv.resetScaleAndCenter(); +// +// } +// } +// mIndicatorTv.setText(String.format("%d/%d", position + 1, urls.size())); +// } +// +// @Override +// public void onPageScrollStateChanged(int newState) { +// +// } +// +// private void loadImageInfo(int position, int width) { +// String url = urls.get(position); +// RetrofitManager.getInstance(this) +// .getApi().getImageInfo(url + "?x-oss-process=image/info") +// .subscribeOn(Schedulers.io()) +// .observeOn(AndroidSchedulers.mainThread()) +// .subscribe(new Response() { +// @Override +// public void onResponse(@Nullable ImageInfoEntity response) { +// if (response != null && response.getImageWidth() != null && +// Integer.valueOf(response.getImageWidth().getValue()) > width) { +// mImageInfoMap.put(url, response); +// if (position == mViewPager.getCurrentItem()) { +// onPageScrolled(position, 0, 0); // 刷新下载原图提示按钮 +// } +// } +// } +// }); +// } +// +// private void loadImage(String url, final BigImageView imageView) { +// if (TextUtils.isEmpty(url)) return; +// +// if (url.startsWith("data:image/png;base64")) { +// AppExecutor.getIoExecutor().execute(() -> { +// String base64String = url.replace("data:image/png;base64", ""); +// try { +// File imageFile = new File(getCacheDir().getAbsolutePath() + File.separator + System.currentTimeMillis() + ".png"); +// +// byte[] decodedString = Base64.decode(base64String, Base64.DEFAULT); +// +// BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(imageFile)); +// bos.write(decodedString); +// bos.flush(); +// bos.close(); +// +// AppExecutor.getUiExecutor().execute(() -> { +// imageView.setImageViewFactory(new FrescoImageViewFactory()); +// imageView.showImage(Uri.fromFile(imageFile)); +// }); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// }); +// } else { +// // 添加GIF支持 +// imageView.setImageViewFactory(new FrescoImageViewFactory()); +// imageView.showImage(Uri.parse(url)); +// } +// } +// +// private class ViewImageAdapter extends PagerAdapter { +// +// @Override +// public int getCount() { +// if (urls == null) { +// return 0; +// } +// return urls.size(); +// } +// +// @SuppressLint("MissingPermission") +// @NonNull +// @Override +// public Object instantiateItem(@NonNull ViewGroup container, int position) { +// String url = urls.get(position); +// ImageRequest imageRequest = ImageRequest.fromUri(url); +// boolean isInMemoryCache = mImagePipeline.isInBitmapMemoryCache(imageRequest); +// boolean isInDiskCache = imageRequest != null && mImagePipeline.isInDiskCacheSync(imageRequest); +// +// Gh_RelativeLayout view = (Gh_RelativeLayout) View.inflate(container.getContext(), R.layout.viewimage_normal_item, null); +// BigImageView imageView = view.findViewById(R.id.viewimage_iv_show); +// +// if (!isInMemoryCache +// && !isInDiskCache +// && !NetworkUtils.isWifiOr4GConnected(ViewImageActivity.this) +// && !url.contains(".gif")) { +// url = ImageUtils.getTransformLimitUrl(url, mLimitWidth, getApplicationContext()); +// } +// +// String finalUrl = url; +// imageView.setImageLoaderCallback(new SimpleImageLoader() { +// @Override +// public void onSuccess(File image) { +// if (!finalUrl.equals(urls.get(position))) { +// BitmapFactory.Options options = new BitmapFactory.Options(); +// options.inJustDecodeBounds = true; +// BitmapFactory.decodeFile(new File(image.getPath()).getAbsolutePath(), options); +// loadImageInfo(position, options.outWidth); // 加载图片参数,目的是用户显示原文按钮 +// } +// SubsamplingScaleImageView ssiv = imageView.getSSIV(); +// if (ssiv != null) { +// ssiv.setMaxScale(10f); // 这个缩放倍数最好很具宽高自动调节 +// ssiv.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() { +// @Override +// public void onReady() { +// ssiv.resetScaleAndCenter(); +// } +// }); +// ssiv.setOnClickListener(v -> finish()); +// +// } +// } +// }); +// loadImage(url, imageView); +// +// //长按 +// imageView.setOnLongClickListener(v -> { +// final Dialog dialog = new Dialog(ViewImageActivity.this); +// +// LinearLayout container1 = new LinearLayout(ViewImageActivity.this); +// container1.setOrientation(LinearLayout.VERTICAL); +// container1.setBackgroundColor(Color.WHITE); +// +// final TextView reportTv = new TextView(ViewImageActivity.this); +// reportTv.setPadding( +// DisplayUtils.dip2px(ViewImageActivity.this, 20), +// DisplayUtils.dip2px(ViewImageActivity.this, 12), +// 0, +// DisplayUtils.dip2px(ViewImageActivity.this, 12)); +// reportTv.setText(R.string.save_pic); +// reportTv.setTextSize(17); +// reportTv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.title)); +// reportTv.setBackgroundResource(R.drawable.textview_white_style); +// int widthPixels = getResources().getDisplayMetrics().widthPixels; +// reportTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10, +// LinearLayout.LayoutParams.WRAP_CONTENT)); +// container1.addView(reportTv); +// +// dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); +// dialog.setContentView(container1); +// +// if (!isFinishing()) { +// dialog.show(); +// } +// +// reportTv.setOnClickListener(v1 -> { +// PermissionHelper.checkStoragePermissionBeforeAction(ViewImageActivity.this, () -> { +// saveImageToFile(imageView.getCurrentImageFile(), finalUrl); +// dialog.cancel(); +// }); +// dialog.cancel(); +// }); +// +// return false; +// }); +// +// view.setTag(position); +// container.addView(view); +// return view; +// } +// +// private void saveImageToFile(File src, String curUrl) { +// InputStream in = null; +// OutputStream out = null; +// try { +// String fileName; +// if (mShowBase64Image) { +// fileName = MD5Utils.getUrlMD5(curUrl.substring(0, 50)) + ".png"; +// } else { +// fileName = curUrl.substring(curUrl.lastIndexOf("/")); +// } +// String savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/ghzhushou/"; +// File file = new File(savePath); +// if (!file.exists()) { +// file.mkdirs(); +// } +// +// File dst = new File(savePath, fileName); +// if (dst.exists()) { +// dst.delete(); +// } +// +// in = new FileInputStream(src); +// out = new FileOutputStream(dst); +// byte[] buf = new byte[1024]; +// int len; +// while ((len = in.read(buf)) > 0) { +// out.write(buf, 0, len); +// } +// +// Utils.toast(ViewImageActivity.this, "图片已保存到/Pictures/ghzhushou/"); +// MessageShareUtils.refreshImage(ViewImageActivity.this, dst); +// } catch (Exception e) { +// Utils.log("图片保存失败:" + e.toString()); +// } finally { +// try { +// if (out != null) out.close(); +// if (in != null) in.close(); +// } catch (Exception ignore) { +// } +// } +// } +// +// +// @Override +// public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { +// container.removeView((View) object); +// } +// +// @Override +// public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { +// return view == object; +// } +// } +//} diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameGalleryAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameGalleryAdapter.kt index 88fd0d3190..15b3f4f707 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameGalleryAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/GameGalleryAdapter.kt @@ -11,8 +11,8 @@ import butterknife.BindView import com.gh.base.BaseRecyclerViewHolder import com.gh.common.util.* import com.gh.common.view.WrapContentDraweeView +import com.gh.gamecenter.ImageViewerActivity import com.gh.gamecenter.R -import com.gh.gamecenter.ViewImageActivity import com.gh.gamecenter.databinding.GalleryVideoItemBinding import com.gh.gamecenter.entity.GameDetailEntity import com.gh.gamecenter.entity.GameEntity @@ -65,7 +65,13 @@ class GameGalleryAdapter(var context: Context, DataCollectionUtils.uploadClick(context, "游戏介绍", "游戏详情") MtaHelper.onEvent("游戏详情_新", "点击游戏截图", mGame.name) - val intent = ViewImageActivity.getViewImageIntent(context, mGallery, holder.adapterPosition, mEntrance) + val intent = ImageViewerActivity.getIntent( + context, + mGallery ?: arrayListOf(), + holder.adapterPosition, + holder.itemView, + mEntrance) + context.startActivity(intent) } } diff --git a/app/src/main/java/com/gh/gamecenter/message/KeFuFragmentAdapter.java b/app/src/main/java/com/gh/gamecenter/message/KeFuFragmentAdapter.java index c37af01e15..561515ad1e 100644 --- a/app/src/main/java/com/gh/gamecenter/message/KeFuFragmentAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/message/KeFuFragmentAdapter.java @@ -27,9 +27,9 @@ import com.gh.common.util.EntranceUtils; import com.gh.common.util.ImageUtils; import com.gh.common.util.MtaHelper; import com.gh.gamecenter.GameDetailActivity; +import com.gh.gamecenter.ImageViewerActivity; import com.gh.gamecenter.NewsDetailActivity; import com.gh.gamecenter.R; -import com.gh.gamecenter.ViewImageActivity; import com.gh.gamecenter.WebActivity; import com.gh.gamecenter.adapter.viewholder.FooterViewHolder; import com.gh.gamecenter.baselist.ListAdapter; @@ -124,7 +124,7 @@ public class KeFuFragmentAdapter extends ListAdapter { draweeView.setImageURI(image); int finalI = i; draweeView.setOnClickListener(v -> { - Intent intent = ViewImageActivity.getViewImageIntent(mContext, + Intent intent = ImageViewerActivity.getIntent(mContext, (ArrayList) images, finalI, "(消息中心-系统)"); diff --git a/app/src/main/java/com/gh/gamecenter/newsdetail/NewsDetailAdapter.java b/app/src/main/java/com/gh/gamecenter/newsdetail/NewsDetailAdapter.java index 3c438001df..dfbb949b6b 100644 --- a/app/src/main/java/com/gh/gamecenter/newsdetail/NewsDetailAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/newsdetail/NewsDetailAdapter.java @@ -45,10 +45,10 @@ import com.gh.common.util.TextHelper; import com.gh.common.view.DrawableView; import com.gh.common.view.RichEditor; import com.gh.gamecenter.GameDetailActivity; +import com.gh.gamecenter.ImageViewerActivity; import com.gh.gamecenter.MessageDetailActivity; import com.gh.gamecenter.NewsDetailActivity; import com.gh.gamecenter.R; -import com.gh.gamecenter.ViewImageActivity; import com.gh.gamecenter.adapter.viewholder.CommentViewHolder; import com.gh.gamecenter.adapter.viewholder.GameDetailNewsViewHolder; import com.gh.gamecenter.adapter.viewholder.NewsDetailCommentListViewHolder; @@ -722,9 +722,9 @@ public class NewsDetailAdapter extends BaseRecyclerAdapter { current = i; } } - Intent intent = ViewImageActivity.getViewImageIntent(mContext, mNewsImgs, current, mEntrance + "+(新闻详情[" + mTitle + "])"); + Intent intent = ImageViewerActivity.getIntent(mContext, mNewsImgs, current, mEntrance + "+(新闻详情[" + mTitle + "])"); if (mContext instanceof Activity) { - ((Activity) mContext).startActivityForResult(intent, ViewImageActivity.REQUEST_FOR_VIEWED_IMAGE); + ((Activity) mContext).startActivityForResult(intent, ImageViewerActivity.REQUEST_FOR_VIEWED_IMAGE); } } } diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt index 51f50da71f..a5550b76ac 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt @@ -14,10 +14,7 @@ import com.gh.base.fragment.BaseFragment_TabLayout import com.gh.common.constant.Constants import com.gh.common.util.* import com.gh.common.view.HorizontalItemDecoration -import com.gh.gamecenter.NewsDetailActivity -import com.gh.gamecenter.R -import com.gh.gamecenter.UserInfoActivity -import com.gh.gamecenter.ViewImageActivity +import com.gh.gamecenter.* import com.gh.gamecenter.databinding.FragmentHomeBinding import com.gh.gamecenter.entity.BadgeEntity import com.gh.gamecenter.entity.GameEntity @@ -34,7 +31,6 @@ import com.gh.gamecenter.personalhome.home.UserHistoryViewModel import com.gh.gamecenter.personalhome.home.UserVideoHistoryFragment import com.gh.gamecenter.user.UserViewModel import com.google.android.material.appbar.AppBarLayout -import com.google.android.material.tabs.TabLayout import com.halo.assistant.HaloApp import com.lightgame.utils.Utils import kotlinx.android.synthetic.main.fragment_home.* @@ -294,7 +290,7 @@ class UserHomeFragment : NormalFragment() { userIcon.setOnClickListener { MtaHelper.onEvent("个人主页详情", "个人主页详情", "头像") - startActivity(ViewImageActivity.getViewImageIntent(requireContext(), arrayListOf(personalData.icon), 0, "$mEntrance+($mPath)")) + startActivity(ImageViewerActivity.getIntent(requireContext(), arrayListOf(personalData.icon), 0, userIcon,"$mEntrance+($mPath)")) } userFollowerContainer.setOnClickListener { MtaHelper.onEvent("个人主页详情", "个人主页详情", "关注数") diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt index 5f0d0195ca..92acd511a1 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt @@ -17,7 +17,6 @@ import android.widget.ImageView import android.widget.LinearLayout import android.widget.PopupWindow import android.widget.TextView -import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.app.ActivityOptionsCompat import androidx.core.content.ContextCompat @@ -39,10 +38,7 @@ import com.gh.common.util.* import com.gh.common.view.DrawableView import com.gh.common.view.ExpandAndCloseTextView import com.gh.common.view.RichEditor -import com.gh.gamecenter.NormalActivity -import com.gh.gamecenter.R -import com.gh.gamecenter.SuggestionActivity -import com.gh.gamecenter.ViewImageActivity +import com.gh.gamecenter.* import com.gh.gamecenter.databinding.FragmentAnswerDetailBinding import com.gh.gamecenter.entity.MeEntity import com.gh.gamecenter.entity.Permissions @@ -231,8 +227,8 @@ class AnswerDetailFragment : NormalFragment() { } } activity?.setResult(Activity.RESULT_OK, data) - } else if (requestCode == ViewImageActivity.REQUEST_FOR_VIEWED_IMAGE && resultCode == Activity.RESULT_OK) { - mViewedImageSet = data.extras?.get(ViewImageActivity.VIEWED_IMAGE) as HashSet + } else if (requestCode == ImageViewerActivity.REQUEST_FOR_VIEWED_IMAGE && resultCode == Activity.RESULT_OK) { + mViewedImageSet = data.extras?.get(ImageViewerActivity.VIEWED_IMAGE) as HashSet } else if (requestCode == CommentActivity.REQUEST_CODE && resultCode == Activity.RESULT_OK) { val count = data.getIntExtra(CommentActivity.COMMENT_COUNT, 0) if (count != 0) { @@ -892,11 +888,11 @@ class AnswerDetailFragment : NormalFragment() { toast("视频审核未通过") } } else { - showQuestionImageDetail(0) + showQuestionImageDetail(view, 0) } } - R.id.questionsdetail_item_pic2 -> showQuestionImageDetail(1 - videoSize) - R.id.questionsdetail_item_pic3 -> showQuestionImageDetail(2 - videoSize) + R.id.questionsdetail_item_pic2 -> showQuestionImageDetail(view, 1 - videoSize) + R.id.questionsdetail_item_pic3 -> showQuestionImageDetail(view, 2 - videoSize) R.id.title_tv -> { // startActivity(QuestionsDetailActivity.getIntent( @@ -952,11 +948,11 @@ class AnswerDetailFragment : NormalFragment() { } } - private fun showQuestionImageDetail(position: Int) { + private fun showQuestionImageDetail(view: View, position: Int) { val images = ArrayList(mViewModel.answerDetail?.question?.images) if (position <= images.size) { - val intent = ViewImageActivity.getViewImageIntent(context, images, position, "$mEntrance+(回答详情)") + val intent = ImageViewerActivity.getIntent(requireContext(), images, position, view, "$mEntrance+(回答详情)") startActivity(intent) } } @@ -967,7 +963,7 @@ class AnswerDetailFragment : NormalFragment() { mAnswerId, mViewModel.answerDetail?.commentCount ?: 0, showKeyBoard) - ActivityCompat.startActivityForResult(requireActivity(),intent, CommentActivity.REQUEST_CODE,optionsCompat.toBundle()) + ActivityCompat.startActivityForResult(requireActivity(), intent, CommentActivity.REQUEST_CODE, optionsCompat.toBundle()) } private fun editAnswer(answerDetail: AnswerDetailEntity) { @@ -1214,9 +1210,9 @@ class AnswerDetailFragment : NormalFragment() { } i++ } - val intent = ViewImageActivity.getViewImageIntent(context, mAnswersImages, current, + val intent = ImageViewerActivity.getIntent(requireContext(), mAnswersImages, current, mEntrance + "+(回答详情[" + mBinding.titleTv.text.toString() + "])") - startActivityForResult(intent, ViewImageActivity.REQUEST_FOR_VIEWED_IMAGE) + startActivityForResult(intent, ImageViewerActivity.REQUEST_FOR_VIEWED_IMAGE) } } } diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt index e4ec20a5a2..3249745143 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt @@ -11,7 +11,6 @@ import android.view.Gravity import android.view.MenuItem import android.view.View import android.view.inputmethod.InputMethodManager -import androidx.core.content.ContextCompat import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import butterknife.OnClick @@ -20,8 +19,8 @@ import com.gh.base.fragment.WaitingDialogFragment import com.gh.common.AppExecutor import com.gh.common.util.* import com.gh.common.view.DrawableView +import com.gh.gamecenter.ImageViewerActivity import com.gh.gamecenter.R -import com.gh.gamecenter.ViewImageActivity import com.gh.gamecenter.databinding.FragmentAnswerEditBinding import com.gh.gamecenter.entity.NotificationUgc import com.gh.gamecenter.manager.UserManager @@ -32,7 +31,6 @@ import com.gh.gamecenter.qa.entity.Questions import com.gh.gamecenter.video.VideoVerifyItemViewHolder import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel import com.halo.assistant.HaloApp -import com.lightgame.utils.Utils import com.zhihu.matisse.Matisse import com.zhihu.matisse.MimeType import org.json.JSONObject @@ -509,21 +507,21 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver { toast("视频审核未通过") } } else { - showQuestionImageDetail(0) + showQuestionImageDetail(view, 0) } } - R.id.question_images_2 -> showQuestionImageDetail(1 - videoSize) - R.id.question_images_3 -> showQuestionImageDetail(2 - videoSize) + R.id.question_images_2 -> showQuestionImageDetail(view, 1 - videoSize) + R.id.question_images_3 -> showQuestionImageDetail(view, 2 - videoSize) R.id.draft_btn -> { startActivityForResult(AnswerDraftActivity.getIntent(this, mViewModel.answerId), ANSWER_DRAFT_REQUEST_CODE) } } } - private fun showQuestionImageDetail(position: Int) { + private fun showQuestionImageDetail(view: View, position: Int) { val images = ArrayList(mViewModel.question.images) if (position <= images.size) { - val intent = ViewImageActivity.getViewImageIntent(this, images, position, "$mEntrance+(回答编辑)") + val intent = ImageViewerActivity.getIntent(this, images, position, view, "$mEntrance+(回答编辑)") startActivity(intent) } } diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailActivity.kt index 54c2214568..97184e5bf6 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailActivity.kt @@ -17,7 +17,6 @@ import android.widget.ImageView import android.widget.LinearLayout import android.widget.PopupWindow import android.widget.TextView -import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.app.ActivityOptionsCompat import androidx.core.content.ContextCompat @@ -33,9 +32,9 @@ import com.gh.common.history.HistoryHelper import com.gh.common.util.* import com.gh.common.view.DrawableView import com.gh.common.view.RichEditor +import com.gh.gamecenter.ImageViewerActivity import com.gh.gamecenter.R import com.gh.gamecenter.SuggestionActivity -import com.gh.gamecenter.ViewImageActivity import com.gh.gamecenter.databinding.ActivityArticleDetailBinding import com.gh.gamecenter.entity.CommunityEntity import com.gh.gamecenter.entity.Permissions @@ -92,8 +91,8 @@ class ArticleDetailActivity : ToolBarActivity() { updateView() } mNoConn.performClick() //重新刷新 - } else if (requestCode == ViewImageActivity.REQUEST_FOR_VIEWED_IMAGE && resultCode == Activity.RESULT_OK) { - val imageSet = data?.extras?.get(ViewImageActivity.VIEWED_IMAGE) as HashSet + } else if (requestCode == ImageViewerActivity.REQUEST_FOR_VIEWED_IMAGE && resultCode == Activity.RESULT_OK) { + val imageSet = data?.extras?.get(ImageViewerActivity.VIEWED_IMAGE) as HashSet // 返回时把点过的图片变为大图 if (mArticleImgs.size > 0) { if (imageSet.size == mArticleImgs.size) { @@ -477,9 +476,9 @@ class ArticleDetailActivity : ToolBarActivity() { } i++ } - val intent = ViewImageActivity.getViewImageIntent(baseContext, mArticleImgs, current, + val intent = ImageViewerActivity.getIntent(baseContext, mArticleImgs, current, mEntrance + "+(社区文章详情[" + mBinding.articleDetailTitle.text.toString() + "])") - startActivityForResult(intent, ViewImageActivity.REQUEST_FOR_VIEWED_IMAGE) + startActivityForResult(intent, ImageViewerActivity.REQUEST_FOR_VIEWED_IMAGE) } } diff --git a/app/src/main/java/com/gh/gamecenter/qa/questions/detail/QuestionsDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/questions/detail/QuestionsDetailFragment.kt index 4980214d95..aa5c0a44ba 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/questions/detail/QuestionsDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/questions/detail/QuestionsDetailFragment.kt @@ -29,9 +29,9 @@ import com.gh.common.TimeElapsedHelper import com.gh.common.constant.Constants.GAME_DETAIL_COME_IN import com.gh.common.util.* import com.gh.common.view.SpacingItemDecoration +import com.gh.gamecenter.ImageViewerActivity import com.gh.gamecenter.R import com.gh.gamecenter.SuggestionActivity -import com.gh.gamecenter.ViewImageActivity import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.baselist.ListFragment import com.gh.gamecenter.baselist.LoadType @@ -280,7 +280,11 @@ class QuestionsDetailFragment : toast("视频审核未通过") } } else if (mQuestionsDetailEntity!!.images.size > imgPosition) { - val intent = ViewImageActivity.getViewImageIntent(context, ArrayList(mQuestionsDetailEntity!!.images), imgPosition, "$mEntrance+(问题详情-答案列表)") + val intent = ImageViewerActivity.getIntent(requireContext(), + ArrayList(mQuestionsDetailEntity!!.images), + imgPosition, + view, + "$mEntrance+(问题详情-答案列表)") startActivity(intent) } } @@ -288,14 +292,22 @@ class QuestionsDetailFragment : if (imgPosition == -1) imgPosition = 1 - videoSize if (imgPosition == -1) imgPosition = 2 - videoSize if (mQuestionsDetailEntity!!.images.size > imgPosition) { - val intent = ViewImageActivity.getViewImageIntent(context, ArrayList(mQuestionsDetailEntity!!.images), imgPosition, "$mEntrance+(问题详情-答案列表)") + val intent = ImageViewerActivity.getIntent(requireContext(), + ArrayList(mQuestionsDetailEntity!!.images), + imgPosition, + view, + "$mEntrance+(问题详情-答案列表)") startActivity(intent) } } R.id.questionsdetail_item_pic3 -> { if (imgPosition == -1) imgPosition = 2 - videoSize if (mQuestionsDetailEntity!!.images.size > imgPosition) { - val intent = ViewImageActivity.getViewImageIntent(context, ArrayList(mQuestionsDetailEntity!!.images), imgPosition, "$mEntrance+(问题详情-答案列表)") + val intent = ImageViewerActivity.getIntent(requireContext(), + ArrayList(mQuestionsDetailEntity!!.images), + imgPosition, + view, + "$mEntrance+(问题详情-答案列表)") startActivity(intent) } } @@ -557,7 +569,7 @@ class QuestionsDetailFragment : private fun getUserAnswerDrafts() { RetrofitManager.getInstance(context).api - .getUserAnswerDrafts(mQuestionsId, "",Utils.getTime(context)) + .getUserAnswerDrafts(mQuestionsId, "", Utils.getTime(context)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : Response() { diff --git a/app/src/main/res/layout/activity_viewimage.xml b/app/src/main/res/layout/activity_viewimage.xml index ae88ca37cf..f052299d6b 100644 --- a/app/src/main/res/layout/activity_viewimage.xml +++ b/app/src/main/res/layout/activity_viewimage.xml @@ -4,17 +4,22 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + android:layout_height="wrap_content" + android:layout_alignParentBottom="true"> + tools:visibility="visible" /> \ No newline at end of file diff --git a/app/src/main/res/layout/viewimage_normal_item.xml b/app/src/main/res/layout/viewimage_normal_item.xml index 3762d80c8f..56098c0552 100644 --- a/app/src/main/res/layout/viewimage_normal_item.xml +++ b/app/src/main/res/layout/viewimage_normal_item.xml @@ -4,7 +4,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> -