Use PhotoView in place of WebView to display images. Implemented a pager to swipe through images.
This commit is contained in:
parent
040c845c15
commit
f6999dd547
@ -138,6 +138,9 @@ dependencies {
|
||||
// Pager
|
||||
implementation 'me.relex:circleindicator:2.0.0@aar'
|
||||
|
||||
//PhotoView
|
||||
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.1.0-beta01'
|
||||
|
||||
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
|
||||
|
@ -62,6 +62,9 @@
|
||||
<activity
|
||||
android:name=".ReaderActivity">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ImageActivity">
|
||||
</activity>
|
||||
|
||||
<meta-data
|
||||
android:name="apps.amine.bou.readerforselfoss.utils.glide.SelfSignedGlideModule"
|
||||
|
@ -0,0 +1,52 @@
|
||||
package apps.amine.bou.readerforselfoss
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter
|
||||
import apps.amine.bou.readerforselfoss.fragments.ImageFragment
|
||||
import kotlinx.android.synthetic.main.activity_reader.*
|
||||
|
||||
class ImageActivity : AppCompatActivity() {
|
||||
private lateinit var allImages : ArrayList<String>
|
||||
private var position : Int = 0
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.activity_image)
|
||||
|
||||
setSupportActionBar(toolBar)
|
||||
supportActionBar?.setDisplayShowTitleEnabled(false)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
|
||||
allImages = intent.getStringArrayListExtra("allImages")
|
||||
position = intent.getIntExtra("position", 0)
|
||||
|
||||
pager.adapter = ScreenSlidePagerAdapter(supportFragmentManager)
|
||||
pager.currentItem = position
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
onBackPressed()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private inner class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
|
||||
|
||||
override fun getCount(): Int {
|
||||
return allImages.size
|
||||
}
|
||||
|
||||
override fun getItem(position: Int): ImageFragment {
|
||||
return ImageFragment.newInstance(allImages[position])
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ import androidx.core.widget.NestedScrollView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.room.Room
|
||||
import apps.amine.bou.readerforselfoss.ImageActivity
|
||||
import apps.amine.bou.readerforselfoss.R
|
||||
import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
|
||||
import apps.amine.bou.readerforselfoss.api.mercury.ParsedContent
|
||||
@ -577,8 +578,10 @@ class ArticleFragment : Fragment() {
|
||||
|
||||
val position : Int = allImages.indexOf(rootView!!.webcontent.hitTestResult.extra)
|
||||
|
||||
|
||||
fragmentManager!!.beginTransaction().replace(R.id.reader_activity_view, ImageFragment.newInstance(position, allImages)).addToBackStack(null).commit()
|
||||
val intent = Intent(activity, ImageActivity::class.java)
|
||||
intent.putExtra("allImages", allImages)
|
||||
intent.putExtra("position", position)
|
||||
startActivity(intent)
|
||||
return false
|
||||
}
|
||||
return false
|
||||
|
@ -1,130 +1,47 @@
|
||||
package apps.amine.bou.readerforselfoss.fragments
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.webkit.WebResourceResponse
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import apps.amine.bou.readerforselfoss.R
|
||||
import apps.amine.bou.readerforselfoss.utils.glide.getBitmapInputStream
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import kotlinx.android.synthetic.main.fragment_article.view.webcontent
|
||||
import java.util.concurrent.ExecutionException
|
||||
import kotlin.math.abs
|
||||
import kotlinx.android.synthetic.main.fragment_image.view.*
|
||||
|
||||
class ImageFragment : Fragment() {
|
||||
|
||||
private var position: Int = 0
|
||||
private lateinit var allImages: ArrayList<String>
|
||||
private lateinit var imageUrl : String
|
||||
private val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
|
||||
position = arguments!!.getInt("position")
|
||||
allImages = arguments!!.getStringArrayList("allImages")
|
||||
|
||||
imageUrl = arguments!!.getString("imageUrl")
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
(activity as AppCompatActivity).supportActionBar?.setDisplayShowTitleEnabled(false)
|
||||
val view : View = inflater.inflate(R.layout.fragment_image, container, false)
|
||||
|
||||
view.webcontent.visibility = View.VISIBLE
|
||||
view.webcontent.settings.setLoadWithOverviewMode(true)
|
||||
view.webcontent.settings.setUseWideViewPort(true)
|
||||
view.webcontent.settings.setSupportZoom(true)
|
||||
view.webcontent.settings.setBuiltInZoomControls(true)
|
||||
view.webcontent.settings.setDisplayZoomControls(false)
|
||||
|
||||
view.webcontent.webViewClient = object : WebViewClient() {
|
||||
override fun shouldInterceptRequest(view: WebView?, url: String): WebResourceResponse? {
|
||||
val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL)
|
||||
if (url.toLowerCase().contains(".jpg") || url.toLowerCase().contains(".jpeg")) {
|
||||
try {
|
||||
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
||||
return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.JPEG))
|
||||
}catch ( e : ExecutionException) {}
|
||||
}
|
||||
else if (url.toLowerCase().contains(".png")) {
|
||||
try {
|
||||
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
||||
return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.PNG))
|
||||
}catch ( e : ExecutionException) {}
|
||||
}
|
||||
else if (url.toLowerCase().contains(".webp")) {
|
||||
try {
|
||||
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
||||
return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.WEBP))
|
||||
}catch ( e : ExecutionException) {}
|
||||
}
|
||||
|
||||
return super.shouldInterceptRequest(view, url)
|
||||
}
|
||||
}
|
||||
|
||||
val gestureDetector = GestureDetector(activity, object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean {
|
||||
val SWIPE_MIN_DISTANCE = 120
|
||||
val SWIPE_MAX_OFF_PATH = 250
|
||||
val SWIPE_THRESHOLD_VELOCITY = 200
|
||||
if (abs(e1!!.y - e2!!.y) > SWIPE_MAX_OFF_PATH)
|
||||
return false
|
||||
if (e1.x - e2.x > SWIPE_MIN_DISTANCE
|
||||
&& abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
|
||||
changeImage(1)
|
||||
}
|
||||
else if (e2.x - e1.x > SWIPE_MIN_DISTANCE
|
||||
&& abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
|
||||
changeImage(-1)
|
||||
}
|
||||
|
||||
return super.onFling(e1, e2, velocityX, velocityY);
|
||||
}
|
||||
})
|
||||
view.webcontent.setOnTouchListener { _, event -> gestureDetector.onTouchEvent(event)}
|
||||
|
||||
view.webcontent.loadUrl(allImages[position])
|
||||
view.photoView.visibility = View.VISIBLE
|
||||
Glide.with(activity)
|
||||
.asBitmap()
|
||||
.apply(glideOptions)
|
||||
.load(imageUrl)
|
||||
.into(view.photoView)
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
menu.clear()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
(activity as AppCompatActivity).supportActionBar?.setDisplayShowTitleEnabled(true)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
fun changeImage(change : Int) {
|
||||
position += change
|
||||
if (position < 0 || position >= allImages.size) {
|
||||
position -= change
|
||||
}
|
||||
else {
|
||||
view!!.webcontent.loadUrl(allImages[position])
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ARG_POSITION = "position"
|
||||
private const val ARG_IMAGES = "allImages"
|
||||
private const val ARG_IMAGE = "imageUrl"
|
||||
|
||||
fun newInstance(
|
||||
position: Int,
|
||||
allImages: ArrayList<String>
|
||||
imageUrl : String
|
||||
): ImageFragment {
|
||||
val fragment = ImageFragment()
|
||||
val args = Bundle()
|
||||
args.putInt(ARG_POSITION, position)
|
||||
args.putStringArrayList(ARG_IMAGES, allImages)
|
||||
args.putString(ARG_IMAGE, imageUrl)
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
}
|
||||
|
33
app/src/main/res/layout/activity_image.xml
Normal file
33
app/src/main/res/layout/activity_image.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:popupTheme="?attr/toolbarPopupTheme"
|
||||
app:theme="@style/ToolBarStyle" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/appBarLayout" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -4,9 +4,13 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<WebView
|
||||
android:id="@+id/webcontent"
|
||||
<com.github.chrisbanes.photoview.PhotoView
|
||||
android:id="@+id/photoView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
</WebView>
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:background="@android:color/black"
|
||||
app:srcCompat="@android:drawable/screen_background_dark" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
Loading…
Reference in New Issue
Block a user