Commit 2fbdfe3a authored by wanglei's avatar wanglei

...

parent e52e19fd
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 androidx.activity.addCallback
import com.base.pdfviewerscannerwhite.databinding.ActivityWordBinding
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
class WordActivity : BaseActivity<ActivityWordBinding>() {
private val TAG = "WordActivity"
override val binding: ActivityWordBinding by lazy {
ActivityWordBinding.inflate(layoutInflater)
}
private lateinit var mPoiViewer: PoiViewer
private var path: String = ""
override fun initView() {
......@@ -17,13 +25,75 @@ class WordActivity : BaseActivity<ActivityWordBinding>() {
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) {
val mPoiViewer = PoiViewer(this)
mPoiViewer = PoiViewer(this)
try {
mPoiViewer.loadFile(binding.mFlDocContainer, sourceFilePath)
} 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 @@
android:fitsSystemWindows="true"
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
android:id="@+id/mFlDocContainer"
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>
\ No newline at end of file
......@@ -15,13 +15,7 @@ import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
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 com.blankj.utilcode.util.UriUtils
import com.cherry.lib.doc.R
......@@ -256,7 +250,7 @@ class DocView : FrameLayout {
mPoiViewer = PoiViewer(context)
}
mPoiViewer?.loadFile(
binding.mFlDocContainer, sourceFilePath
binding.mFlDocContainer, sourceFilePath ?: ""
)
} catch (e: Exception) {
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;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.ContextWrapper;
import android.os.AsyncTask;
import android.text.Html;
import android.text.SpannableString;
import android.text.TextUtils;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.cherry.lib.doc.util.WordConverter;
import org.apache.commons.io.FileUtils;
import java.io.File;
public class PoiViewer {
private Context mContext;
private ViewGroup mRootView;
private String mFilePath;
private String mFileExt;
private String mFileCachePath;
private WebView mWebView;
private ProgressDialog mProgressDialog;
public PoiViewer(Context context) {
mContext = context;
initView();
initCacheDir();
package com.cherry.lib.doc.widget
import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.content.Context
import android.content.ContextWrapper
import android.os.AsyncTask
import android.text.Html
import android.text.SpannableString
import android.text.TextUtils
import android.view.ViewGroup
import android.webkit.WebSettings
import android.webkit.WebView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.cherry.lib.doc.util.WordConverter
import org.apache.commons.io.FileUtils
import java.io.File
class PoiViewer(private var mContext: Context) {
private val TAG = "PoiViewer"
private var mFilePath: String = ""
private var mFileExt: String = ""
private var mFileCachePath: String = ""
private var mProgressDialog: ProgressDialog? = null
private lateinit var mRootView: ViewGroup
private lateinit var mWebView: WebView
init {
initView()
initCacheDir()
}
@SuppressLint("SetJavaScriptEnabled")
private void initView() {
mProgressDialog = new ProgressDialog(mContext);
mProgressDialog.setMessage("正在加载文件...");
var singleTapAction: (() -> Unit)? = null
@SuppressLint("SetJavaScriptEnabled", "ClickableViewAccessibility")
private fun initView() {
mProgressDialog = ProgressDialog(mContext)
mProgressDialog?.setMessage("loading...")
// 初始化网页
mWebView = new WebView(mContext);
mWebView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.getSettings().setAllowFileAccess(true);
mWebView.getSettings().setAllowFileAccessFromFileURLs(true);
mWebView.getSettings().setAllowUniversalAccessFromFileURLs(true);
mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
mWebView.getSettings().setSupportZoom(true);
mWebView.getSettings().setBuiltInZoomControls(true);
mWebView.getSettings().setDisplayZoomControls(false);
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.getSettings().setTextZoom(128);
mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
mWebView = WebView(mContext)
mWebView.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
mWebView.getSettings().javaScriptEnabled = true
mWebView.getSettings().domStorageEnabled = true
mWebView.getSettings().allowFileAccess = true
mWebView.getSettings().allowFileAccessFromFileURLs = true
mWebView.getSettings().allowUniversalAccessFromFileURLs = true
mWebView.getSettings().cacheMode = WebSettings.LOAD_NO_CACHE
mWebView.getSettings().setSupportZoom(true)
mWebView.getSettings().builtInZoomControls = true
mWebView.getSettings().displayZoomControls = false
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() {
mFileCachePath = mContext.getCacheDir().getAbsolutePath() + "/poiCache/";
File file = new File(mFileCachePath);
private fun initCacheDir() {
mFileCachePath = mContext.cacheDir.absolutePath + "/poiCache/"
val file = File(mFileCachePath)
if (!file.exists()) {
file.mkdir();
file.mkdir()
}
}
public void loadFile(ViewGroup fileLayout, String filePath) {
mRootView = fileLayout;
mFilePath = filePath;
mFileExt = filePath.substring(filePath.lastIndexOf("."));
mProgressDialog.show();
new ConvertTask().execute(filePath);
fun loadFile(fileLayout: ViewGroup, filePath: String) {
mRootView = fileLayout
mFilePath = filePath
mFileExt = filePath.substring(filePath.lastIndexOf("."))
mProgressDialog!!.show()
ConvertTask().execute(filePath)
}
public class ConvertTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... objects) {
String filePath = objects[0];
if (mFileExt.equalsIgnoreCase(".doc") || mFileExt.equalsIgnoreCase(".docx")) {
WordConverter wordConverter = new WordConverter(filePath, mFileCachePath);
return wordConverter.returnPath;
@SuppressLint("StaticFieldLeak")
inner class ConvertTask : AsyncTask<String?, Void?, String?>() {
@Deprecated("Deprecated in Java")
override fun doInBackground(vararg params: String?): String? {
val filePath = params[0] ?: ""
if (mFileExt.equals(".doc", ignoreCase = true) || mFileExt.equals(".docx", ignoreCase = true)) {
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.readExcelToHtml();
// return excelConverter.mUrlPath;
// }
if (mFileExt.equalsIgnoreCase(".txt")) {
return if (mFileExt.equals(".txt", ignoreCase = true)) {
try {
String txtString = FileUtils.readFileToString(new File(filePath), "UTF-8");
SpannableString spanString = new SpannableString(txtString);
String htmlString = Html.toHtml(spanString);
String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1);
String htmlName = fileName.replace(fileExt, "html");
File tempFile = new File(mFileCachePath, htmlName);
FileUtils.writeStringToFile(tempFile, htmlString, "UTF-8");
return "file:///" + tempFile.getAbsolutePath();
} catch (Exception e) {
return null;
val txtString = FileUtils.readFileToString(File(filePath), "UTF-8")
val spanString = SpannableString(txtString)
val htmlString = Html.toHtml(spanString)
val fileName = filePath.substring(filePath.lastIndexOf("/") + 1)
val fileExt = fileName.substring(fileName.lastIndexOf(".") + 1)
val htmlName = fileName.replace(fileExt, "html")
val tempFile = File(mFileCachePath, htmlName)
FileUtils.writeStringToFile(tempFile, htmlString, "UTF-8")
"file:///" + tempFile.absolutePath
} catch (e: Exception) {
null
}
}
return null;
} else null
}
@Override
protected void onPostExecute(String returnString) {
mProgressDialog.dismiss();
override fun onPostExecute(returnString: String?) {
mProgressDialog!!.dismiss()
if (TextUtils.isEmpty(returnString)) {
Toast.makeText(mContext, "文件打开失败", Toast.LENGTH_SHORT).show();
scanForActivity(mContext).finish();
return;
Toast.makeText(mContext, "open failed", Toast.LENGTH_SHORT).show()
scanForActivity(mContext)!!.finish()
return
}
mWebView.loadUrl(returnString);
mRootView.addView(mWebView);
mWebView.loadUrl(returnString!!)
mRootView.addView(mWebView)
}
}
public void recycle() {
mWebView.removeAllViews();
mWebView = null;
mContext = null;
fun recycle() {
mWebView.removeAllViews()
}
public AppCompatActivity scanForActivity(Context context) {
if (context == null) return null;
if (context instanceof AppCompatActivity) {
return (AppCompatActivity) context;
} else if (context instanceof ContextWrapper) {
ContextWrapper cw = (ContextWrapper) context;
return scanForActivity(cw.getBaseContext());
fun scanForActivity(context: Context?): AppCompatActivity? {
if (context == null) return null
if (context is AppCompatActivity) {
return context
} else if (context is ContextWrapper) {
return scanForActivity(context.baseContext)
}
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