Commit 2fbdfe3a authored by wanglei's avatar wanglei

...

parent e52e19fd
package com.base.pdfviewerscannerwhite.ui.document.word package com.base.pdfviewerscannerwhite.ui.document.word
import android.view.View
import android.view.animation.Animation
import android.view.animation.TranslateAnimation
import android.widget.Toast import android.widget.Toast
import androidx.activity.addCallback
import com.base.pdfviewerscannerwhite.databinding.ActivityWordBinding import com.base.pdfviewerscannerwhite.databinding.ActivityWordBinding
import com.base.pdfviewerscannerwhite.helper.BaseActivity import com.base.pdfviewerscannerwhite.helper.BaseActivity
import com.base.pdfviewerscannerwhite.utils.KeyBoardUtils.hideKeyboard
import com.base.pdfviewerscannerwhite.utils.LogEx
import com.cherry.lib.doc.widget.PoiViewer import com.cherry.lib.doc.widget.PoiViewer
class WordActivity : BaseActivity<ActivityWordBinding>() { class WordActivity : BaseActivity<ActivityWordBinding>() {
private val TAG = "WordActivity"
override val binding: ActivityWordBinding by lazy { override val binding: ActivityWordBinding by lazy {
ActivityWordBinding.inflate(layoutInflater) ActivityWordBinding.inflate(layoutInflater)
} }
private lateinit var mPoiViewer: PoiViewer
private var path: String = "" private var path: String = ""
override fun initView() { override fun initView() {
...@@ -17,13 +25,75 @@ class WordActivity : BaseActivity<ActivityWordBinding>() { ...@@ -17,13 +25,75 @@ class WordActivity : BaseActivity<ActivityWordBinding>() {
word2Html(path) word2Html(path)
} }
override fun initListener() {
super.initListener()
onBackPressedDispatcher.addCallback {
finishToMain()
}
binding.flFanhui.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
mPoiViewer.singleTapAction = {
LogEx.logDebug(TAG, "singleTapAction")
if (isShowTopLayout) {
LogEx.logDebug(TAG, "hide")
hideTopLayout()
} else {
showTopLayout()
LogEx.logDebug(TAG, "show")
}
}
}
private fun word2Html(sourceFilePath: String) { private fun word2Html(sourceFilePath: String) {
val mPoiViewer = PoiViewer(this) mPoiViewer = PoiViewer(this)
try { try {
mPoiViewer.loadFile(binding.mFlDocContainer, sourceFilePath) mPoiViewer.loadFile(binding.mFlDocContainer, sourceFilePath)
} catch (e: java.lang.Exception) { } catch (e: java.lang.Exception) {
Toast.makeText(this, "打开失败", Toast.LENGTH_SHORT).show() Toast.makeText(this, "open failed", Toast.LENGTH_SHORT).show()
}
}
private var isShowTopLayout = true
private fun showTopLayout() {
if (!isShowTopLayout) {
isShowTopLayout = true
val topAnim: Animation = TranslateAnimation(0f, 0f, -binding.vAnimatorTop.height.toFloat(), 0f)
topAnim.setDuration(200)
topAnim.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {
binding.vAnimatorTop.visibility = View.VISIBLE
}
override fun onAnimationRepeat(animation: Animation) {}
override fun onAnimationEnd(animation: Animation) {
}
})
binding.vAnimatorTop.startAnimation(topAnim)
} }
} }
private fun hideTopLayout() {
if (isShowTopLayout) {
isShowTopLayout = false
hideKeyboard(binding.editSearch)
val topAnim: Animation = TranslateAnimation(0f, 0f, 0f, -binding.vAnimatorTop.height.toFloat())
topAnim.setDuration(200)
topAnim.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {}
override fun onAnimationRepeat(animation: Animation) {}
override fun onAnimationEnd(animation: Animation) {
binding.vAnimatorTop.visibility = View.GONE
}
})
binding.vAnimatorTop.startAnimation(topAnim)
}
}
} }
\ No newline at end of file
...@@ -7,9 +7,116 @@ ...@@ -7,9 +7,116 @@
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
tools:context=".ui.document.word.WordActivity"> tools:context=".ui.document.word.WordActivity">
<ViewAnimator
android:id="@+id/v_animator_top"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/white"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_top"
android:layout_width="match_parent"
android:layout_height="60dp"
app:layout_constraintTop_toTopOf="parent">
<FrameLayout
android:id="@+id/fl_fanhui"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/tv_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="15dp"
android:src="@mipmap/fanhui_b"
tools:ignore="ContentDescription" />
</FrameLayout>
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@color/black"
android:textSize="19sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/iv_xuanzhuan"
app:layout_constraintStart_toEndOf="@id/fl_fanhui"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText"
tools:text="DEMO.docx" />
<ImageView
android:id="@+id/iv_xuanzhuan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:src="@mipmap/hengping"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/iv_search"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/iv_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:src="@mipmap/h_sousuo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/iv_more"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/iv_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:src="@mipmap/x_genduo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<EditText
android:id="@+id/edit_search"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginStart="5dp"
android:layout_marginEnd="20dp"
android:background="@drawable/bg_f8f9fe_10"
android:hint="input..."
android:paddingHorizontal="18dp"
android:singleLine="true"
android:textColor="@color/black"
android:textColorHint="#B8B9BD"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/iv_search"
app:layout_constraintStart_toEndOf="@id/fl_fanhui"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="Autofill,HardcodedText,TextFields" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ViewAnimator>
<FrameLayout <FrameLayout
android:id="@+id/mFlDocContainer" android:id="@+id/mFlDocContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/v_animator_top" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -15,13 +15,7 @@ import android.view.ViewGroup ...@@ -15,13 +15,7 @@ import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.RelativeLayout import android.widget.RelativeLayout
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import coil.load import coil.load
import com.blankj.utilcode.util.UriUtils import com.blankj.utilcode.util.UriUtils
import com.cherry.lib.doc.R import com.cherry.lib.doc.R
...@@ -256,7 +250,7 @@ class DocView : FrameLayout { ...@@ -256,7 +250,7 @@ class DocView : FrameLayout {
mPoiViewer = PoiViewer(context) mPoiViewer = PoiViewer(context)
} }
mPoiViewer?.loadFile( mPoiViewer?.loadFile(
binding.mFlDocContainer, sourceFilePath binding.mFlDocContainer, sourceFilePath ?: ""
) )
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
......
package com.cherry.lib.doc.widget
import android.annotation.SuppressLint
import android.util.Log
import android.view.MotionEvent
import android.view.View
import kotlin.math.sqrt
const val TAP_THRESHOLD = 200
const val TAP_INTERVAL = 250
class MyOnTouchLister : View.OnTouchListener {
private val TAG = "MyOnTouchLister"
private var lastActionDownTime = 0L
var singleTapAction: (() -> Unit)? = null
private var lastX = 0f
private var lastY = 0f
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View, event: MotionEvent): Boolean {
Log.e(TAG, "onTouch")
when (event.action) {
MotionEvent.ACTION_DOWN -> {
Log.e(TAG, "ACTION_DOWN")
lastActionDownTime = System.currentTimeMillis()
// 记录按下时的位置
lastX = event.x
lastY = event.y
}
MotionEvent.ACTION_UP -> {
val flag1 = (System.currentTimeMillis() - lastActionDownTime) < TAP_INTERVAL
val deltaX = event.x - lastX
val deltaY = event.y - lastY
val flag2 = moveSqrt(deltaX, deltaY) < TAP_THRESHOLD
if (flag1 && flag2) {
Log.e(TAG, "ACTION_UP flag1=$flag1 flag2=$flag2")
singleTapAction?.invoke()
}
}
}
return false
}
private fun moveSqrt(deltaX: Float, deltaY: Float): Double {
return sqrt((deltaX * deltaX + deltaY * deltaY).toDouble())
}
}
\ No newline at end of file
package com.cherry.lib.doc.widget; package com.cherry.lib.doc.widget
import android.annotation.SuppressLint; import android.annotation.SuppressLint
import android.app.ProgressDialog; import android.app.ProgressDialog
import android.content.Context; import android.content.Context
import android.content.ContextWrapper; import android.content.ContextWrapper
import android.os.AsyncTask; import android.os.AsyncTask
import android.text.Html; import android.text.Html
import android.text.SpannableString; import android.text.SpannableString
import android.text.TextUtils; import android.text.TextUtils
import android.view.ViewGroup; import android.view.ViewGroup
import android.webkit.WebSettings; import android.webkit.WebSettings
import android.webkit.WebView; import android.webkit.WebView
import android.widget.Toast; import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity; import com.cherry.lib.doc.util.WordConverter
import org.apache.commons.io.FileUtils
import com.cherry.lib.doc.util.WordConverter; import java.io.File
import org.apache.commons.io.FileUtils; class PoiViewer(private var mContext: Context) {
private val TAG = "PoiViewer"
import java.io.File; private var mFilePath: String = ""
private var mFileExt: String = ""
public class PoiViewer { private var mFileCachePath: String = ""
private var mProgressDialog: ProgressDialog? = null
private Context mContext;
private ViewGroup mRootView; private lateinit var mRootView: ViewGroup
private lateinit var mWebView: WebView
private String mFilePath;
private String mFileExt; init {
initView()
private String mFileCachePath; initCacheDir()
private WebView mWebView;
private ProgressDialog mProgressDialog;
public PoiViewer(Context context) {
mContext = context;
initView();
initCacheDir();
} }
@SuppressLint("SetJavaScriptEnabled") var singleTapAction: (() -> Unit)? = null
private void initView() {
mProgressDialog = new ProgressDialog(mContext); @SuppressLint("SetJavaScriptEnabled", "ClickableViewAccessibility")
mProgressDialog.setMessage("正在加载文件..."); private fun initView() {
mProgressDialog = ProgressDialog(mContext)
mProgressDialog?.setMessage("loading...")
// 初始化网页 // 初始化网页
mWebView = new WebView(mContext); mWebView = WebView(mContext)
mWebView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); mWebView.layoutParams = ViewGroup.LayoutParams(
mWebView.getSettings().setJavaScriptEnabled(true); ViewGroup.LayoutParams.MATCH_PARENT,
mWebView.getSettings().setDomStorageEnabled(true); ViewGroup.LayoutParams.MATCH_PARENT
mWebView.getSettings().setAllowFileAccess(true); )
mWebView.getSettings().setAllowFileAccessFromFileURLs(true); mWebView.getSettings().javaScriptEnabled = true
mWebView.getSettings().setAllowUniversalAccessFromFileURLs(true); mWebView.getSettings().domStorageEnabled = true
mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); mWebView.getSettings().allowFileAccess = true
mWebView.getSettings().setSupportZoom(true); mWebView.getSettings().allowFileAccessFromFileURLs = true
mWebView.getSettings().setBuiltInZoomControls(true); mWebView.getSettings().allowUniversalAccessFromFileURLs = true
mWebView.getSettings().setDisplayZoomControls(false); mWebView.getSettings().cacheMode = WebSettings.LOAD_NO_CACHE
mWebView.getSettings().setUseWideViewPort(true); mWebView.getSettings().setSupportZoom(true)
mWebView.getSettings().setLoadWithOverviewMode(true); mWebView.getSettings().builtInZoomControls = true
mWebView.getSettings().setTextZoom(128); mWebView.getSettings().displayZoomControls = false
mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); mWebView.getSettings().useWideViewPort = true
mWebView.getSettings().loadWithOverviewMode = true
mWebView.getSettings().textZoom = 128
mWebView.getSettings().layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
val lister = MyOnTouchLister()
lister.singleTapAction = {
singleTapAction?.invoke()
}
mWebView.setOnTouchListener(lister)
} }
private void initCacheDir() { private fun initCacheDir() {
mFileCachePath = mContext.getCacheDir().getAbsolutePath() + "/poiCache/"; mFileCachePath = mContext.cacheDir.absolutePath + "/poiCache/"
File file = new File(mFileCachePath); val file = File(mFileCachePath)
if (!file.exists()) { if (!file.exists()) {
file.mkdir(); file.mkdir()
} }
} }
public void loadFile(ViewGroup fileLayout, String filePath) { fun loadFile(fileLayout: ViewGroup, filePath: String) {
mRootView = fileLayout; mRootView = fileLayout
mFilePath = filePath; mFilePath = filePath
mFileExt = filePath.substring(filePath.lastIndexOf(".")); mFileExt = filePath.substring(filePath.lastIndexOf("."))
mProgressDialog.show(); mProgressDialog!!.show()
new ConvertTask().execute(filePath); ConvertTask().execute(filePath)
} }
public class ConvertTask extends AsyncTask<String, Void, String> { @SuppressLint("StaticFieldLeak")
@Override inner class ConvertTask : AsyncTask<String?, Void?, String?>() {
protected String doInBackground(String... objects) { @Deprecated("Deprecated in Java")
String filePath = objects[0]; override fun doInBackground(vararg params: String?): String? {
if (mFileExt.equalsIgnoreCase(".doc") || mFileExt.equalsIgnoreCase(".docx")) { val filePath = params[0] ?: ""
WordConverter wordConverter = new WordConverter(filePath, mFileCachePath); if (mFileExt.equals(".doc", ignoreCase = true) || mFileExt.equals(".docx", ignoreCase = true)) {
return wordConverter.returnPath; val wordConverter = WordConverter(filePath, mFileCachePath)
return wordConverter.returnPath
} }
// if (mFileExt.equalsIgnoreCase(".xls") || mFileExt.equalsIgnoreCase(".xlsx")) { // if (mFileExt.equalsIgnoreCase(".xls") || mFileExt.equalsIgnoreCase(".xlsx")) {
// ExcelConverter excelConverter = new ExcelConverter(filePath, mFileCachePath); // ExcelConverter excelConverter = new ExcelConverter(filePath, mFileCachePath);
// excelConverter.readExcelToHtml(); // excelConverter.readExcelToHtml();
// return excelConverter.mUrlPath; // return excelConverter.mUrlPath;
// } // }
if (mFileExt.equalsIgnoreCase(".txt")) { return if (mFileExt.equals(".txt", ignoreCase = true)) {
try { try {
String txtString = FileUtils.readFileToString(new File(filePath), "UTF-8"); val txtString = FileUtils.readFileToString(File(filePath), "UTF-8")
SpannableString spanString = new SpannableString(txtString); val spanString = SpannableString(txtString)
String htmlString = Html.toHtml(spanString); val htmlString = Html.toHtml(spanString)
String fileName = filePath.substring(filePath.lastIndexOf("/") + 1); val fileName = filePath.substring(filePath.lastIndexOf("/") + 1)
String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1); val fileExt = fileName.substring(fileName.lastIndexOf(".") + 1)
String htmlName = fileName.replace(fileExt, "html"); val htmlName = fileName.replace(fileExt, "html")
File tempFile = new File(mFileCachePath, htmlName); val tempFile = File(mFileCachePath, htmlName)
FileUtils.writeStringToFile(tempFile, htmlString, "UTF-8"); FileUtils.writeStringToFile(tempFile, htmlString, "UTF-8")
return "file:///" + tempFile.getAbsolutePath(); "file:///" + tempFile.absolutePath
} catch (Exception e) { } catch (e: Exception) {
return null; null
} }
} } else null
return null;
} }
@Override
protected void onPostExecute(String returnString) { override fun onPostExecute(returnString: String?) {
mProgressDialog.dismiss(); mProgressDialog!!.dismiss()
if (TextUtils.isEmpty(returnString)) { if (TextUtils.isEmpty(returnString)) {
Toast.makeText(mContext, "文件打开失败", Toast.LENGTH_SHORT).show(); Toast.makeText(mContext, "open failed", Toast.LENGTH_SHORT).show()
scanForActivity(mContext).finish(); scanForActivity(mContext)!!.finish()
return; return
} }
mWebView.loadUrl(returnString); mWebView.loadUrl(returnString!!)
mRootView.addView(mWebView); mRootView.addView(mWebView)
} }
} }
public void recycle() { fun recycle() {
mWebView.removeAllViews(); mWebView.removeAllViews()
mWebView = null;
mContext = null;
} }
public AppCompatActivity scanForActivity(Context context) { fun scanForActivity(context: Context?): AppCompatActivity? {
if (context == null) return null; if (context == null) return null
if (context instanceof AppCompatActivity) { if (context is AppCompatActivity) {
return (AppCompatActivity) context; return context
} else if (context instanceof ContextWrapper) { } else if (context is ContextWrapper) {
ContextWrapper cw = (ContextWrapper) context; return scanForActivity(context.baseContext)
return scanForActivity(cw.getBaseContext());
} }
return null; return null
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment