Commit c7a1e38b authored by wanglei's avatar wanglei

...

parent 9fa8260b
......@@ -19,9 +19,6 @@
android:theme="@style/Theme.PDFViewerScannerWhite"
android:usesCleartextTraffic="true"
tools:targetApi="34">
<activity
android:name=".ui.document.ppt.PptActivity"
android:exported="false" />
<meta-data
android:name="com.google.android.gms.version"
......@@ -49,6 +46,12 @@
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.document.ppt.PptActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.document.excel.ExcelActivity"
android:exported="false"
......@@ -58,7 +61,9 @@
<activity
android:name=".ui.document.word.WordActivity"
android:exported="false"
android:theme="@style/Theme.PDFViewerScannerWhite" />
android:screenOrientation="portrait"
android:theme="@style/Theme.PDFViewerScannerWhite"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.document.pdf.PdfMergeActivity"
android:exported="false"
......
......@@ -2,6 +2,7 @@ package com.base.pdfviewerscannerwhite.ui.main
import android.annotation.SuppressLint
import android.net.Uri
import android.provider.MediaStore
import android.view.View
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
......@@ -20,6 +21,7 @@ import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatTime2
import com.base.pdfviewerscannerwhite.utils.LogEx
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkStorePermission
import com.base.pdfviewerscannerwhite.utils.ToastUtils.toast
import com.base.pdfviewerscannerwhite.utils.updateMediaStore
class MainActivity : BaseActivity<ActivityMainBinding>(), MainView {
......@@ -81,7 +83,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), MainView {
if (!checkStorePermission()) {
showStoragePermission(launcher)
updateMediaStore()
}
}
private fun initTabLayout() {
......
......@@ -28,6 +28,10 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding = true
}
}
dependencies {
......
......@@ -6,7 +6,7 @@ import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.cherry.lib.doc.bean.DocEngine
import com.cherry.lib.doc.util.Constant
import kotlinx.android.synthetic.main.activity_doc_viewer.mDocView
import com.cherry.lib.doc.widget.DocView
open class DocViewerActivity : AppCompatActivity() {
private val TAG = "DocViewerActivity"
......@@ -16,7 +16,7 @@ open class DocViewerActivity : AppCompatActivity() {
activity: AppCompatActivity, docSourceType: Int, path: String?,
fileType: Int? = null, engine: Int? = null
) {
var intent = Intent(activity, DocViewerActivity::class.java)
val intent = Intent(activity, DocViewerActivity::class.java)
intent.putExtra(Constant.INTENT_SOURCE_KEY, docSourceType)
intent.putExtra(Constant.INTENT_DATA_KEY, path)
intent.putExtra(Constant.INTENT_TYPE_KEY, fileType)
......@@ -34,6 +34,8 @@ open class DocViewerActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_doc_viewer)
initView()
initData(intent)
}
......@@ -47,7 +49,13 @@ open class DocViewerActivity : AppCompatActivity() {
fileType = intent?.getIntExtra(Constant.INTENT_TYPE_KEY, -1) ?: -1
engine = intent?.getIntExtra(Constant.INTENT_ENGINE_KEY, DocEngine.INTERNAL.value) ?: DocEngine.INTERNAL.value
mDocView.openDoc(this,docUrl,docSourceType,fileType,false, DocEngine.values().first { it.value == engine })
findViewById<DocView>(R.id.mDocView).openDoc(
this,
docUrl,
docSourceType,
fileType,
false,
DocEngine.values().first { it.value == engine })
Log.e(TAG, "initData-docUrl = $docUrl")
Log.e(TAG, "initData-docSourceType = $docSourceType")
Log.e(TAG, "initData-fileType = $fileType")
......
......@@ -5,7 +5,6 @@ import android.graphics.Bitmap;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.View;
import com.blankj.utilcode.util.AppUtils;
import com.cherry.lib.doc.office.common.IOfficeToPicture;
import com.cherry.lib.doc.office.constant.EventConstant;
......@@ -13,7 +12,6 @@ import com.cherry.lib.doc.office.constant.wp.WPViewConstant;
import com.cherry.lib.doc.office.res.ResKit;
import com.cherry.lib.doc.office.system.IMainFrame;
import com.cherry.lib.doc.office.system.MainControl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
......@@ -217,7 +215,7 @@ public abstract class IOffice implements IMainFrame {
* 是否绘制页码
*/
public boolean isDrawPageNumber() {
return true;
return false;
}
/**
......
......@@ -17,13 +17,9 @@
package com.cherry.lib.doc.office.fc.hslf.model;
import java.io.ByteArrayOutputStream;
import com.cherry.lib.doc.office.fc.ddf.EscherClientDataRecord;
import com.cherry.lib.doc.office.fc.ddf.EscherContainerRecord;
import com.cherry.lib.doc.office.fc.ddf.EscherProperties;
import com.cherry.lib.doc.office.fc.hslf.exceptions.HSLFException;
import com.cherry.lib.doc.office.fc.hslf.record.*;
import com.cherry.lib.doc.office.fc.hslf.record.Record;
import com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow;
......@@ -32,8 +28,7 @@ import com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow;
*
* @author Yegor Kozlov
*/
public final class MovieShape extends Picture
{
public final class MovieShape extends Picture {
public static final int DEFAULT_MOVIE_THUMBNAIL = -1;
public static final int MOVIE_MPEG = 1;
......@@ -42,10 +37,9 @@ public final class MovieShape extends Picture
/**
* Create a new <code>Picture</code>
*
* @param pictureIdx the index of the picture
* @param pictureIdx the index of the picture
*/
public MovieShape(int movieIdx, int pictureIdx)
{
public MovieShape(int movieIdx, int pictureIdx) {
super(pictureIdx, null);
setMovieIndex(movieIdx);
setAutoPlay(true);
......@@ -54,24 +48,22 @@ public final class MovieShape extends Picture
/**
* Create a new <code>Picture</code>
*
* @param idx the index of the picture
* @param idx the index of the picture
* @param parent the parent shape
*/
public MovieShape(int movieIdx, int idx, Shape parent)
{
public MovieShape(int movieIdx, int idx, Shape parent) {
super(idx, parent);
setMovieIndex(movieIdx);
}
/**
* Create a <code>Picture</code> object
*
* @param escherRecord the <code>EscherSpContainer</code> record which holds information about
* this picture in the <code>Slide</code>
* @param parent the parent shape of this picture
*/
protected MovieShape(EscherContainerRecord escherRecord, Shape parent)
{
* Create a <code>Picture</code> object
*
* @param escherRecord the <code>EscherSpContainer</code> record which holds information about
* this picture in the <code>Slide</code>
* @param parent the parent shape of this picture
*/
protected MovieShape(EscherContainerRecord escherRecord, Shape parent) {
super(escherRecord, parent);
}
......@@ -80,8 +72,7 @@ public final class MovieShape extends Picture
*
* @return the created <code>EscherContainerRecord</code> which holds shape data
*/
protected EscherContainerRecord createSpContainer(int idx, boolean isChild)
{
protected EscherContainerRecord createSpContainer(int idx, boolean isChild) {
_escherContainer = super.createSpContainer(idx, isChild);
/*setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x1000100);
......@@ -112,7 +103,8 @@ public final class MovieShape extends Picture
{
throw new HSLFException(e);
}
cldata.setRemainingData(out.toByteArray())*/;
cldata.setRemainingData(out.toByteArray())*/
;
return _escherContainer;
}
......@@ -120,17 +112,15 @@ public final class MovieShape extends Picture
/**
* Assign a movie to this shape
*
* @param idx the index of the movie
* @see com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow#addMovie(String, int)
* @param idx the index of the movie
*/
public void setMovieIndex(int idx)
{
OEShapeAtom oe = (OEShapeAtom)getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
public void setMovieIndex(int idx) {
OEShapeAtom oe = (OEShapeAtom) getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
oe.setOptions(idx);
AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if (an != null)
{
AnimationInfo an = (AnimationInfo) getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if (an != null) {
AnimationInfoAtom ai = an.getAnimationInfoAtom();
ai.setDimColor(0x07000000);
ai.setFlag(AnimationInfoAtom.Automatic, true);
......@@ -140,21 +130,17 @@ public final class MovieShape extends Picture
}
}
public void setAutoPlay(boolean flag)
{
AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if (an != null)
{
public void setAutoPlay(boolean flag) {
AnimationInfo an = (AnimationInfo) getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if (an != null) {
an.getAnimationInfoAtom().setFlag(AnimationInfoAtom.Automatic, flag);
updateClientData();
}
}
public boolean isAutoPlay()
{
AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if (an != null)
{
public boolean isAutoPlay() {
AnimationInfo an = (AnimationInfo) getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if (an != null) {
return an.getAnimationInfoAtom().getFlag(AnimationInfoAtom.Automatic);
}
return false;
......@@ -163,27 +149,23 @@ public final class MovieShape extends Picture
/**
* @return UNC or local path to a video file
*/
public String getPath()
{
OEShapeAtom oe = (OEShapeAtom)getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
public String getPath() {
OEShapeAtom oe = (OEShapeAtom) getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
int idx = oe.getOptions();
SlideShow ppt = getSheet().getSlideShow();
ExObjList lst = (ExObjList)ppt.getDocumentRecord().findFirstOfType(
RecordTypes.ExObjList.typeID);
ExObjList lst = (ExObjList) ppt.getDocumentRecord().findFirstOfType(
RecordTypes.ExObjList.typeID);
if (lst == null)
return null;
Record[] r = lst.getChildRecords();
for (int i = 0; i < r.length; i++)
{
if (r[i] instanceof ExMCIMovie)
{
ExMCIMovie mci = (ExMCIMovie)r[i];
for (int i = 0; i < r.length; i++) {
if (r[i] instanceof ExMCIMovie) {
ExMCIMovie mci = (ExMCIMovie) r[i];
ExVideoContainer exVideo = mci.getExVideo();
int objectId = exVideo.getExMediaAtom().getObjectId();
if (objectId == idx)
{
if (objectId == idx) {
return exVideo.getPathAtom().getText();
}
}
......
......@@ -23,6 +23,7 @@ import java.util.Vector;
import com.cherry.lib.doc.office.fc.hslf.model.textproperties.AutoNumberTextProp;
import com.cherry.lib.doc.office.fc.hslf.model.textproperties.TextPropCollection;
import com.cherry.lib.doc.office.fc.hslf.record.*;
import com.cherry.lib.doc.office.fc.hslf.record.Record;
import com.cherry.lib.doc.office.fc.hslf.usermodel.RichTextRun;
import com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow;
import com.cherry.lib.doc.office.fc.util.StringUtil;
......@@ -30,14 +31,13 @@ import com.cherry.lib.doc.office.fc.util.StringUtil;
/**
* This class represents a run of text in a powerpoint document. That
* run could be text on a sheet, or text in a note.
* It is only a very basic class for now
* run could be text on a sheet, or text in a note.
* It is only a very basic class for now
*
* @author Nick Burch
*/
public final class TextRun
{
public final class TextRun {
/**
* all text run records that follow TextHeaderAtom.
* (there can be misc InteractiveInfo, TxInteractiveInfo and other records)
......@@ -45,43 +45,37 @@ public final class TextRun
protected Record[] _records;
/**
* Constructs a Text Run from a Unicode text block
*
* @param tha the TextHeaderAtom that defines what's what
* @param tca the TextCharsAtom containing the text
* @param sta the StyleTextPropAtom which defines the character stylings
*/
public TextRun(TextHeaderAtom tha, TextCharsAtom tca, StyleTextPropAtom sta)
{
* Constructs a Text Run from a Unicode text block
*
* @param tha the TextHeaderAtom that defines what's what
* @param tca the TextCharsAtom containing the text
* @param sta the StyleTextPropAtom which defines the character stylings
*/
public TextRun(TextHeaderAtom tha, TextCharsAtom tca, StyleTextPropAtom sta) {
this(tha, null, tca, sta);
}
/**
* Constructs a Text Run from a Ascii text block
*
* @param tha the TextHeaderAtom that defines what's what
* @param tba the TextBytesAtom containing the text
* @param sta the StyleTextPropAtom which defines the character stylings
*/
public TextRun(TextHeaderAtom tha, TextBytesAtom tba, StyleTextPropAtom sta)
{
* Constructs a Text Run from a Ascii text block
*
* @param tha the TextHeaderAtom that defines what's what
* @param tba the TextBytesAtom containing the text
* @param sta the StyleTextPropAtom which defines the character stylings
*/
public TextRun(TextHeaderAtom tha, TextBytesAtom tba, StyleTextPropAtom sta) {
this(tha, tba, null, sta);
}
/**
* Internal constructor and initializer
*/
private TextRun(TextHeaderAtom tha, TextBytesAtom tba, TextCharsAtom tca, StyleTextPropAtom sta)
{
private TextRun(TextHeaderAtom tha, TextBytesAtom tba, TextCharsAtom tca, StyleTextPropAtom sta) {
_headerAtom = tha;
_styleAtom = sta;
if (tba != null)
{
if (tba != null) {
_byteAtom = tba;
_isUnicode = false;
}
else
{
} else {
_charAtom = tca;
_isUnicode = true;
}
......@@ -90,8 +84,7 @@ public final class TextRun
// Figure out the rich text runs
LinkedList pStyles = new LinkedList();
LinkedList cStyles = new LinkedList();
if (_styleAtom != null)
{
if (_styleAtom != null) {
// Get the style atom to grok itself
_styleAtom.setParentTextSize(runRawText.length());
pStyles = _styleAtom.getParagraphStyles();
......@@ -100,17 +93,13 @@ public final class TextRun
buildRichTextRuns(pStyles, cStyles, runRawText);
}
public void buildRichTextRuns(LinkedList pStyles, LinkedList cStyles, String runRawText)
{
public void buildRichTextRuns(LinkedList pStyles, LinkedList cStyles, String runRawText) {
// Handle case of no current style, with a default
if (pStyles.size() == 0 || cStyles.size() == 0)
{
if (pStyles.size() == 0 || cStyles.size() == 0) {
_rtRuns = new RichTextRun[1];
_rtRuns[0] = new RichTextRun(this, 0, runRawText.length());
}
else
{
} else {
// Build up Rich Text Runs, one for each
// character/paragraph style pair
Vector rtrs = new Vector();
......@@ -123,27 +112,23 @@ public final class TextRun
int cLenRemain = -1;
// Build one for each run with the same style
while (pos <= runRawText.length() && curP < pStyles.size() && curC < cStyles.size())
{
while (pos <= runRawText.length() && curP < pStyles.size() && curC < cStyles.size()) {
// Get the Props to use
TextPropCollection pProps = (TextPropCollection)pStyles.get(curP);
TextPropCollection cProps = (TextPropCollection)cStyles.get(curC);
TextPropCollection pProps = (TextPropCollection) pStyles.get(curP);
TextPropCollection cProps = (TextPropCollection) cStyles.get(curC);
int pLen = pProps.getCharactersCovered();
int cLen = cProps.getCharactersCovered();
// Handle new pass
boolean freshSet = false;
if (pLenRemain == -1 && cLenRemain == -1)
{
if (pLenRemain == -1 && cLenRemain == -1) {
freshSet = true;
}
if (pLenRemain == -1)
{
if (pLenRemain == -1) {
pLenRemain = pLen;
}
if (cLenRemain == -1)
{
if (cLenRemain == -1) {
cLenRemain = cLen;
}
......@@ -153,8 +138,7 @@ public final class TextRun
boolean cShared = false;
// Same size, new styles - neither shared
if (pLen == cLen && freshSet)
{
if (pLen == cLen && freshSet) {
runLen = cLen;
pShared = false;
cShared = false;
......@@ -162,20 +146,16 @@ public final class TextRun
curC++;
pLenRemain = -1;
cLenRemain = -1;
}
else
{
} else {
// Some sharing
// See if we are already in a shared block
if (pLenRemain < pLen)
{
if (pLenRemain < pLen) {
// Existing shared p block
pShared = true;
// Do we end with the c block, or either side of it?
if (pLenRemain == cLenRemain)
{
if (pLenRemain == cLenRemain) {
// We end at the same time
cShared = false;
runLen = pLenRemain;
......@@ -183,18 +163,14 @@ public final class TextRun
curC++;
pLenRemain = -1;
cLenRemain = -1;
}
else if (pLenRemain < cLenRemain)
{
} else if (pLenRemain < cLenRemain) {
// We end before the c block
cShared = true;
runLen = pLenRemain;
curP++;
cLenRemain -= pLenRemain;
pLenRemain = -1;
}
else
{
} else {
// We end after the c block
cShared = false;
runLen = cLenRemain;
......@@ -202,15 +178,12 @@ public final class TextRun
pLenRemain -= cLenRemain;
cLenRemain = -1;
}
}
else if (cLenRemain < cLen)
{
} else if (cLenRemain < cLen) {
// Existing shared c block
cShared = true;
// Do we end with the p block, or either side of it?
if (pLenRemain == cLenRemain)
{
if (pLenRemain == cLenRemain) {
// We end at the same time
pShared = false;
runLen = cLenRemain;
......@@ -218,18 +191,14 @@ public final class TextRun
curC++;
pLenRemain = -1;
cLenRemain = -1;
}
else if (cLenRemain < pLenRemain)
{
} else if (cLenRemain < pLenRemain) {
// We end before the p block
pShared = true;
runLen = cLenRemain;
curC++;
pLenRemain -= cLenRemain;
cLenRemain = -1;
}
else
{
} else {
// We end after the p block
pShared = false;
runLen = pLenRemain;
......@@ -237,12 +206,9 @@ public final class TextRun
cLenRemain -= pLenRemain;
pLenRemain = -1;
}
}
else
{
} else {
// Start of a shared block
if (pLenRemain < cLenRemain)
{
if (pLenRemain < cLenRemain) {
// Shared c block
pShared = false;
cShared = true;
......@@ -250,9 +216,7 @@ public final class TextRun
curP++;
cLenRemain -= pLenRemain;
pLenRemain = -1;
}
else
{
} else {
// Shared p block
pShared = true;
cShared = false;
......@@ -268,14 +232,13 @@ public final class TextRun
int prevPos = pos;
pos += runLen;
// Adjust for end-of-run extra 1 length
if (pos > runRawText.length())
{
if (pos > runRawText.length()) {
runLen--;
}
// Save
RichTextRun rtr = new RichTextRun(this, prevPos, runLen, pProps, cProps, pShared,
cShared);
cShared);
rtrs.add(rtr);
}
......@@ -290,13 +253,12 @@ public final class TextRun
/**
* Adds the supplied text onto the end of the TextRun,
* creating a new RichTextRun (returned) for it to
* sit in.
* creating a new RichTextRun (returned) for it to
* sit in.
* In many cases, before calling this, you'll want to add
* a newline onto the end of your last RichTextRun
* a newline onto the end of your last RichTextRun
*/
public RichTextRun appendText(String s)
{
public RichTextRun appendText(String s) {
// We will need a StyleTextProp atom
ensureStyleAtomPresent();
......@@ -310,22 +272,20 @@ public final class TextRun
// extra character onto the new ones
int pOverRun = _styleAtom.getParagraphTextLengthCovered() - oldSize;
int cOverRun = _styleAtom.getCharacterTextLengthCovered() - oldSize;
if (pOverRun > 0)
{
TextPropCollection tpc = (TextPropCollection)_styleAtom.getParagraphStyles().getLast();
if (pOverRun > 0) {
TextPropCollection tpc = (TextPropCollection) _styleAtom.getParagraphStyles().getLast();
tpc.updateTextSize(tpc.getCharactersCovered() - pOverRun);
}
if (cOverRun > 0)
{
TextPropCollection tpc = (TextPropCollection)_styleAtom.getCharacterStyles().getLast();
if (cOverRun > 0) {
TextPropCollection tpc = (TextPropCollection) _styleAtom.getCharacterStyles().getLast();
tpc.updateTextSize(tpc.getCharactersCovered() - cOverRun);
}
// Next, add the styles for its paragraph and characters
TextPropCollection newPTP = _styleAtom
.addParagraphTextPropCollection(s.length() + pOverRun);
.addParagraphTextPropCollection(s.length() + pOverRun);
TextPropCollection newCTP = _styleAtom
.addCharacterTextPropCollection(s.length() + cOverRun);
.addCharacterTextPropCollection(s.length() + cOverRun);
// Now, create the new RichTextRun
RichTextRun nr = new RichTextRun(this, oldSize, s.length(), newPTP, newCTP, false, false);
......@@ -342,36 +302,28 @@ public final class TextRun
/**
* Saves the given string to the records. Doesn't
* touch the stylings.
* touch the stylings.
*/
private void storeText(String s)
{
private void storeText(String s) {
// Remove a single trailing \r, as there is an implicit one at the
// end of every record
if (s.endsWith("\r"))
{
if (s.endsWith("\r")) {
s = s.substring(0, s.length() - 1);
}
// Store in the appropriate record
if (_isUnicode)
{
if (_isUnicode) {
// The atom can safely convert to unicode
_charAtom.setText(s);
}
else
{
} else {
// Will it fit in a 8 bit atom?
boolean hasMultibyte = StringUtil.hasMultibyte(s);
if (!hasMultibyte)
{
if (!hasMultibyte) {
// Fine to go into 8 bit atom
byte[] text = new byte[s.length()];
StringUtil.putCompressedUnicode(s, text, 0);
_byteAtom.setText(text);
}
else
{
} else {
// Need to swap a TextBytesAtom for a TextCharsAtom
// Build the new TextCharsAtom
......@@ -381,11 +333,9 @@ public final class TextRun
// Use the TextHeaderAtom to do the swap on the parent
RecordContainer parent = _headerAtom.getParentRecord();
Record[] cr = parent.getChildRecords();
for (int i = 0; i < cr.length; i++)
{
for (int i = 0; i < cr.length; i++) {
// Look for TextBytesAtom
if (cr[i].equals(_byteAtom))
{
if (cr[i].equals(_byteAtom)) {
// Found it, so replace, then all done
cr[i] = _charAtom;
break;
......@@ -402,13 +352,10 @@ public final class TextRun
* otherwise the ppt will be corrupted
*/
if (_records != null)
for (int i = 0; i < _records.length; i++)
{
if (_records[i] instanceof TextSpecInfoAtom)
{
TextSpecInfoAtom specAtom = (TextSpecInfoAtom)_records[i];
if ((s.length() + 1) != specAtom.getCharactersCovered())
{
for (int i = 0; i < _records.length; i++) {
if (_records[i] instanceof TextSpecInfoAtom) {
TextSpecInfoAtom specAtom = (TextSpecInfoAtom) _records[i];
if ((s.length() + 1) != specAtom.getCharactersCovered()) {
specAtom.reset(s.length() + 1);
}
}
......@@ -417,22 +364,19 @@ public final class TextRun
/**
* Handles an update to the text stored in one of the Rich Text Runs
*
* @param run
* @param s
*/
public void changeTextInRichTextRun(RichTextRun run, String s)
{
public void changeTextInRichTextRun(RichTextRun run, String s) {
// Figure out which run it is
int runID = -1;
for (int i = 0; i < _rtRuns.length; i++)
{
if (run.equals(_rtRuns[i]))
{
for (int i = 0; i < _rtRuns.length; i++) {
if (run.equals(_rtRuns[i])) {
runID = i;
}
}
if (runID == -1)
{
if (runID == -1) {
throw new IllegalArgumentException("Supplied RichTextRun wasn't from this TextRun");
}
......@@ -452,25 +396,18 @@ public final class TextRun
TextPropCollection pCol = run._getRawParagraphStyle();
TextPropCollection cCol = run._getRawCharacterStyle();
int newSize = s.length();
if (runID == _rtRuns.length - 1)
{
if (runID == _rtRuns.length - 1) {
newSize++;
}
if (run._isParagraphStyleShared())
{
if (run._isParagraphStyleShared()) {
pCol.updateTextSize(pCol.getCharactersCovered() - run.getLength() + s.length());
}
else
{
} else {
pCol.updateTextSize(newSize);
}
if (run._isCharacterStyleShared())
{
if (run._isCharacterStyleShared()) {
cCol.updateTextSize(cCol.getCharactersCovered() - run.getLength() + s.length());
}
else
{
} else {
cCol.updateTextSize(newSize);
}
......@@ -478,30 +415,23 @@ public final class TextRun
// As we go through, update the start position for all subsequent runs
// The building relies on the old text still being present
StringBuffer newText = new StringBuffer();
for (int i = 0; i < _rtRuns.length; i++)
{
for (int i = 0; i < _rtRuns.length; i++) {
int newStartPos = newText.length();
// Build up the new text
if (i != runID)
{
if (i != runID) {
// Not the affected run, so keep old text
newText.append(_rtRuns[i].getRawText());
}
else
{
} else {
// Affected run, so use new text
newText.append(s);
}
// Do we need to update the start position of this run?
// (Need to get the text before we update the start pos)
if (i <= runID)
{
if (i <= runID) {
// Change is after this, so don't need to change start position
}
else
{
} else {
// Change has occured, so update start position
_rtRuns[i].updateStartPosition(newStartPos);
}
......@@ -513,18 +443,16 @@ public final class TextRun
/**
* Changes the text, and sets it all to have the same styling
* as the the first character has.
* as the the first character has.
* If you care about styling, do setText on a RichTextRun instead
*/
public void setRawText(String s)
{
public void setRawText(String s) {
// Save the new text to the atoms
storeText(s);
RichTextRun fst = _rtRuns[0];
// Finally, zap and re-do the RichTextRuns
for (int i = 0; i < _rtRuns.length; i++)
{
for (int i = 0; i < _rtRuns.length; i++) {
_rtRuns[i] = null;
}
_rtRuns = new RichTextRun[1];
......@@ -535,24 +463,19 @@ public final class TextRun
// no change, stays with no styling
// If there is styling:
// everthing gets the same style that the first block has
if (_styleAtom != null)
{
if (_styleAtom != null) {
LinkedList pStyles = _styleAtom.getParagraphStyles();
while (pStyles.size() > 1)
{
while (pStyles.size() > 1) {
pStyles.removeLast();
}
LinkedList cStyles = _styleAtom.getCharacterStyles();
while (cStyles.size() > 1)
{
while (cStyles.size() > 1) {
cStyles.removeLast();
}
_rtRuns[0].setText(s);
}
else
{
} else {
// Recreate rich text run with no styling
_rtRuns[0] = new RichTextRun(this, 0, s.length());
}
......@@ -563,20 +486,17 @@ public final class TextRun
* Changes the text.
* Converts '\r' into '\n'
*/
public void setText(String s)
{
public void setText(String s) {
String text = normalize(s);
setRawText(text);
}
/**
* Ensure a StyleTextPropAtom is present for this run,
* by adding if required. Normally for internal TextRun use.
* by adding if required. Normally for internal TextRun use.
*/
public void ensureStyleAtomPresent()
{
if (_styleAtom != null)
{
public void ensureStyleAtomPresent() {
if (_styleAtom != null) {
// All there
return;
}
......@@ -589,21 +509,19 @@ public final class TextRun
// Add the new StyleTextPropAtom after the TextCharsAtom / TextBytesAtom
Record addAfter = _byteAtom;
if (_byteAtom == null)
{
if (_byteAtom == null) {
addAfter = _charAtom;
}
runAtomsParent.addChildAfter(_styleAtom, addAfter);
// Feed this to our sole rich text run
if (_rtRuns.length != 1)
{
if (_rtRuns.length != 1) {
throw new IllegalStateException(
"Needed to add StyleTextPropAtom when had many rich text runs");
"Needed to add StyleTextPropAtom when had many rich text runs");
}
// These are the only styles for now
_rtRuns[0].supplyTextProps((TextPropCollection)_styleAtom.getParagraphStyles().get(0),
(TextPropCollection)_styleAtom.getCharacterStyles().get(0), false, false);
_rtRuns[0].supplyTextProps((TextPropCollection) _styleAtom.getParagraphStyles().get(0),
(TextPropCollection) _styleAtom.getCharacterStyles().get(0), false, false);
}
// Accesser methods follow
......@@ -612,8 +530,7 @@ public final class TextRun
* Returns the text content of the run, which has been made safe
* for printing and other use.
*/
public String getText()
{
public String getText() {
String rawText = getRawText();
// PowerPoint seems to store files with \r as the line break
......@@ -631,19 +548,17 @@ public final class TextRun
{
text = text.replace((char)0x0B, ' ');
}*/
text = text.replace((char)0x0B, '\u000b');
text = text.replace((char) 0x0B, '\u000b');
return text;
}
/**
* Returns the raw text content of the run. This hasn't had any
* changes applied to it, and so is probably unlikely to print
* out nicely.
*/
public String getRawText()
{
if (_isUnicode)
{
* Returns the raw text content of the run. This hasn't had any
* changes applied to it, and so is probably unlikely to print
* out nicely.
*/
public String getRawText() {
if (_isUnicode) {
return _charAtom.getText();
}
return _byteAtom.getText();
......@@ -651,31 +566,30 @@ public final class TextRun
/**
* Fetch the rich text runs (runs of text with the same styling) that
* are contained within this block of text
* are contained within this block of text
*/
public RichTextRun[] getRichTextRuns()
{
public RichTextRun[] getRichTextRuns() {
return _rtRuns;
}
/**
* Returns the type of the text, from the TextHeaderAtom.
* Possible values can be seen from TextHeaderAtom
* @see com.cherry.lib.doc.office.fc.hslf.record.TextHeaderAtom
*/
public int getRunType()
{
* Returns the type of the text, from the TextHeaderAtom.
* Possible values can be seen from TextHeaderAtom
*
* @see com.cherry.lib.doc.office.fc.hslf.record.TextHeaderAtom
*/
public int getRunType() {
return _headerAtom.getTextType();
}
/**
* Changes the type of the text. Values should be taken
* from TextHeaderAtom. No checking is done to ensure you
* set this to a valid value!
* @see com.cherry.lib.doc.office.fc.hslf.record.TextHeaderAtom
*/
public void setRunType(int type)
{
* Changes the type of the text. Values should be taken
* from TextHeaderAtom. No checking is done to ensure you
* set this to a valid value!
*
* @see com.cherry.lib.doc.office.fc.hslf.record.TextHeaderAtom
*/
public void setRunType(int type) {
_headerAtom.setTextType(type);
}
......@@ -683,57 +597,48 @@ public final class TextRun
* Supply the SlideShow we belong to.
* Also passes it on to our child RichTextRuns
*/
public void supplySlideShow(SlideShow ss)
{
public void supplySlideShow(SlideShow ss) {
slideShow = ss;
if (_rtRuns != null)
{
for (int i = 0; i < _rtRuns.length; i++)
{
if (_rtRuns != null) {
for (int i = 0; i < _rtRuns.length; i++) {
_rtRuns[i].supplySlideShow(slideShow);
}
}
}
public void setSheet(Sheet sheet)
{
public void setSheet(Sheet sheet) {
this._sheet = sheet;
}
public Sheet getSheet()
{
public Sheet getSheet() {
return this._sheet;
}
/**
* @return Shape ID
* @return Shape ID
*/
protected int getShapeId()
{
protected int getShapeId() {
return shapeId;
}
/**
* @param id Shape ID
* @param id Shape ID
*/
protected void setShapeId(int id)
{
protected void setShapeId(int id) {
shapeId = id;
}
/**
* @return 0-based index of the text run in the SLWT container
* @return 0-based index of the text run in the SLWT container
*/
protected int getIndex()
{
protected int getIndex() {
return slwtIndex;
}
/**
* @param id 0-based index of the text run in the SLWT container
* @param id 0-based index of the text run in the SLWT container
*/
protected void setIndex(int id)
{
protected void setIndex(int id) {
slwtIndex = id;
}
......@@ -743,8 +648,7 @@ public final class TextRun
* @return the array of all hyperlinks in this text run
* or <code>null</code> if not found.
*/
public Hyperlink[] getHyperlinks()
{
public Hyperlink[] getHyperlinks() {
return Hyperlink.find(this);
}
......@@ -754,10 +658,8 @@ public final class TextRun
* @param pos 0-based index in the text
* @return RichTextRun or null if not found
*/
public RichTextRun getRichTextRunAt(int pos)
{
for (int i = 0; i < _rtRuns.length; i++)
{
public RichTextRun getRichTextRunAt(int pos) {
for (int i = 0; i < _rtRuns.length; i++) {
int start = _rtRuns[i].getStartIndex();
int end = _rtRuns[i].getEndIndex();
if (pos >= start && pos < end)
......@@ -766,16 +668,12 @@ public final class TextRun
return null;
}
public TextRulerAtom getTextRuler()
{
if (_ruler == null)
{
public TextRulerAtom getTextRuler() {
if (_ruler == null) {
if (_records != null)
for (int i = 0; i < _records.length; i++)
{
if (_records[i] instanceof TextRulerAtom)
{
_ruler = (TextRulerAtom)_records[i];
for (int i = 0; i < _records.length; i++) {
if (_records[i] instanceof TextRulerAtom) {
_ruler = (TextRulerAtom) _records[i];
break;
}
}
......@@ -785,11 +683,9 @@ public final class TextRun
}
public TextRulerAtom createTextRuler()
{
public TextRulerAtom createTextRuler() {
_ruler = getTextRuler();
if (_ruler == null)
{
if (_ruler == null) {
_ruler = TextRulerAtom.getParagraphInstance();
_headerAtom.getParentRecord().appendChildRecord(_ruler);
}
......@@ -799,8 +695,7 @@ public final class TextRun
/**
* Returns a new string with line breaks converted into internal ppt representation
*/
public String normalize(String s)
{
public String normalize(String s) {
String ns = s.replaceAll("\\r?\\n", "\r");
return ns;
}
......@@ -810,46 +705,39 @@ public final class TextRun
*
* @return text run records
*/
public Record[] getRecords()
{
public Record[] getRecords() {
return _records;
}
/**
*
* @return
*/
public ExtendedParagraphAtom getExtendedParagraphAtom()
{
public ExtendedParagraphAtom getExtendedParagraphAtom() {
return _extendedParagraphAtom;
}
/**
* get bullet and number ruler
*
* @param extendedParaAtom
*/
public void setExtendedParagraphAtom(ExtendedParagraphAtom extendedParaAtom)
{
public void setExtendedParagraphAtom(ExtendedParagraphAtom extendedParaAtom) {
_extendedParagraphAtom = extendedParaAtom;
}
/**
* get number type
*
* @return
*/
public int getNumberingType(int characterIndex)
{
if (_extendedParagraphAtom != null)
{
public int getNumberingType(int characterIndex) {
if (_extendedParagraphAtom != null) {
int index = getAutoNumberIndex(characterIndex);
if (index >= 0)
{
LinkedList<AutoNumberTextProp> paraPropList = _extendedParagraphAtom.getExtendedParagraphPropList();
if (paraPropList != null && paraPropList.size() > 0 && index < paraPropList.size())
{
if (index >= 0) {
LinkedList<AutoNumberTextProp> paraPropList = _extendedParagraphAtom.getExtendedParagraphPropList();
if (paraPropList != null && paraPropList.size() > 0 && index < paraPropList.size()) {
AutoNumberTextProp paraProp = paraPropList.get(index);
if (paraProp != null)
{
if (paraProp != null) {
return paraProp.getNumberingType();
}
}
......@@ -857,24 +745,20 @@ public final class TextRun
}
return -1;
}
/**
* get number start
*
* @return
*/
public int getNumberingStart(int characterIndex)
{
if (_extendedParagraphAtom != null)
{
public int getNumberingStart(int characterIndex) {
if (_extendedParagraphAtom != null) {
int index = getAutoNumberIndex(characterIndex);
if (index >= 0)
{
LinkedList<AutoNumberTextProp> paraPropList = _extendedParagraphAtom.getExtendedParagraphPropList();
if (paraPropList != null && paraPropList.size() > 0 && index < paraPropList.size())
{
if (index >= 0) {
LinkedList<AutoNumberTextProp> paraPropList = _extendedParagraphAtom.getExtendedParagraphPropList();
if (paraPropList != null && paraPropList.size() > 0 && index < paraPropList.size()) {
AutoNumberTextProp paraProp = paraPropList.get(index);
if (paraProp != null)
{
if (paraProp != null) {
return paraProp.getStart();
}
}
......@@ -882,23 +766,18 @@ public final class TextRun
}
return 0;
}
/**
* charcater startoffset
* @param charcterIndex
*
* @return
*/
public int getAutoNumberIndex(int characterIndex)
{
if (_records != null)
{
for (int i = 0; i < _records.length; i++)
{
if (_records[i] instanceof StyleTextPropAtom)
{
StyleTextPropAtom stp = (StyleTextPropAtom)_records[i];
if (stp != null)
{
public int getAutoNumberIndex(int characterIndex) {
if (_records != null) {
for (int i = 0; i < _records.length; i++) {
if (_records[i] instanceof StyleTextPropAtom) {
StyleTextPropAtom stp = (StyleTextPropAtom) _records[i];
if (stp != null) {
return stp.getAutoNumberIndex(characterIndex);
}
}
......@@ -906,55 +785,46 @@ public final class TextRun
}
return -1;
}
/**
*
*
*/
public void dispose()
{
public void dispose() {
slideShow = null;
_sheet = null;
if (_headerAtom != null)
{
if (_headerAtom != null) {
_headerAtom.dispose();
_headerAtom = null;
}
if (_byteAtom != null)
{
if (_byteAtom != null) {
_byteAtom.dispose();
_byteAtom = null;
}
if (_charAtom != null)
{
if (_charAtom != null) {
_charAtom.dispose();
_charAtom = null;
}
if (_styleAtom != null)
{
if (_styleAtom != null) {
_styleAtom.dispose();
_styleAtom = null;
}
if (_ruler != null)
{
if (_ruler != null) {
_ruler.dispose();
_ruler = null;
}
if (_extendedParagraphAtom != null)
{
if (_extendedParagraphAtom != null) {
_extendedParagraphAtom.dispose();
_extendedParagraphAtom = null;
}
if (_rtRuns != null)
{
for (RichTextRun rt : _rtRuns)
{
if (_rtRuns != null) {
for (RichTextRun rt : _rtRuns) {
rt.dispose();
}
_rtRuns = null;
}
}
// Note: These fields are protected to help with unit testing
// Other classes shouldn't really go playing with them!
protected TextHeaderAtom _headerAtom;
......
......@@ -29,7 +29,6 @@ import com.cherry.lib.doc.office.system.SysKit;
import com.cherry.lib.doc.office.system.beans.pagelist.APageListItem;
import com.cherry.lib.doc.office.system.beans.pagelist.APageListView;
import com.cherry.lib.doc.office.system.beans.pagelist.IPageListViewListener;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
......@@ -275,8 +274,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener
}
/**
* @param x 为100%的值
* @param y 为100%的值
* /
public long viewToModel(int x, int y, boolean isBack)
{
......@@ -484,7 +481,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener
/**
* page list view moving position
* @param position horizontal or vertical
*/
public int getPageListViewMovingPosition()
{
......@@ -515,7 +511,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener
* @param e2 MotionEvent instance
* @param velocityX x axis velocity
* @param velocityY y axis velocity
* @param eventNethodType event method
* @see IMainFrame#ON_CLICK
* @see IMainFrame#ON_DOUBLE_TAP
* @see IMainFrame#ON_DOUBLE_TAP_EVENT
......@@ -653,7 +648,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener
/**
* 绘制页信息
* @param canvas
* @param zoom
*/
private void drawPageNubmer(Canvas canvas)
{
......@@ -692,8 +686,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener
* set change page flag, Only when effectively the PageSize greater than ViewSize.
* (for PPT, word print mode, PDF)
*
* @param b = true, change page
* = false, don't change page
*/
public boolean isChangePage()
{
......
......@@ -7,14 +7,12 @@ import android.view.View
import android.view.ViewGroup
import android.view.animation.AlphaAnimation
import android.view.animation.LinearInterpolator
import android.widget.Toast
import androidx.core.view.updateLayoutParams
import android.widget.ImageView
import android.widget.ProgressBar
import androidx.recyclerview.widget.RecyclerView
import com.cherry.lib.doc.R
import com.cherry.lib.doc.util.ViewUtils.hide
import com.cherry.lib.doc.util.ViewUtils.show
import kotlinx.android.synthetic.main.page_item_pdf.view.*
import kotlinx.android.synthetic.main.pdf_view_page_loading_layout.view.*
/*
* -----------------------------------------------------------------
......@@ -31,13 +29,14 @@ internal class PdfPageViewAdapter(
private val renderer: PdfRendererCore?,
private val pageSpacing: Rect,
private val enableLoadingForPages: Boolean
) :
RecyclerView.Adapter<PdfPageViewAdapter.PdfPageViewHolder>() {
) : RecyclerView.Adapter<PdfPageViewAdapter.PdfPageViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PdfPageViewHolder {
return PdfPageViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.page_item_pdf,parent,
false)
LayoutInflater.from(parent.context).inflate(
R.layout.page_item_pdf, parent,
false
)
)
}
......@@ -49,21 +48,22 @@ internal class PdfPageViewAdapter(
holder.bindView()
}
inner class PdfPageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),View.OnAttachStateChangeListener {
inner class PdfPageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnAttachStateChangeListener {
fun bindView() {
}
private fun handleLoadingForPage(position: Int) {
val progressBar = itemView.findViewById<ProgressBar>(R.id.pdf_view_page_loading_progress)
if (!enableLoadingForPages) {
itemView.pdf_view_page_loading_progress.hide()
progressBar.hide()
return
}
if (renderer?.pageExistInCache(position) == true) {
itemView.pdf_view_page_loading_progress.hide()
progressBar.hide()
} else {
itemView.pdf_view_page_loading_progress.show()
progressBar.show()
}
}
......@@ -84,20 +84,22 @@ internal class PdfPageViewAdapter(
// this.rightMargin = pageSpacing.right
// this.bottomMargin = pageSpacing.bottom
// }
itemView.pageView.setImageBitmap(bitmap)
itemView.pageView.animation = AlphaAnimation(0F, 1F).apply {
val pageView = itemView.findViewById<ImageView>(R.id.pageView)
pageView.setImageBitmap(bitmap)
pageView.animation = AlphaAnimation(0F, 1F).apply {
interpolator = LinearInterpolator()
duration = 200
}
itemView.pdf_view_page_loading_progress.hide()
itemView.findViewById<ProgressBar>(R.id.pdf_view_page_loading_progress).hide()
}
}
}
}
override fun onViewDetachedFromWindow(p0: View) {
itemView.pageView.setImageBitmap(null)
itemView.pageView.clearAnimation()
val pageView = itemView.findViewById<ImageView>(R.id.pageView)
pageView.setImageBitmap(null)
pageView.clearAnimation()
}
}
}
\ No newline at end of file
......@@ -14,12 +14,10 @@ import android.widget.Toast
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.RecyclerView
import com.cherry.lib.doc.R
import com.cherry.lib.doc.databinding.ListItemPdfBinding
import com.cherry.lib.doc.interfaces.OnPdfItemClickListener
import com.cherry.lib.doc.util.ViewUtils.hide
import com.cherry.lib.doc.util.ViewUtils.show
import kotlinx.android.synthetic.main.doc_view.view.mIvPdf
import kotlinx.android.synthetic.main.list_item_pdf.view.*
import kotlinx.android.synthetic.main.pdf_view_page_loading_layout.view.*
/*
* -----------------------------------------------------------------
......@@ -41,8 +39,10 @@ internal class PdfViewAdapter(
RecyclerView.Adapter<PdfViewAdapter.PdfPageViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PdfPageViewHolder {
return PdfPageViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.list_item_pdf,parent,
false)
LayoutInflater.from(parent.context).inflate(
R.layout.list_item_pdf, parent,
false
)
)
}
......@@ -59,24 +59,24 @@ internal class PdfViewAdapter(
holder.bindView()
}
inner class PdfPageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),View.OnAttachStateChangeListener {
inner class PdfPageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnAttachStateChangeListener {
val binding = ListItemPdfBinding.bind(itemView)
fun bindView() {
itemView.container_view.setOnClickListener {
binding.containerView.setOnClickListener {
listener?.OnPdfItemClick(adapterPosition)
}
}
private fun handleLoadingForPage(position: Int) {
if (!enableLoadingForPages) {
itemView.pdf_view_page_loading_progress.hide()
binding.include.pdfViewPageLoadingProgress.hide()
return
}
if (renderer?.pageExistInCache(position) == true) {
itemView.pdf_view_page_loading_progress.hide()
binding.include.pdfViewPageLoadingProgress.hide()
} else {
itemView.pdf_view_page_loading_progress.show()
binding.include.pdfViewPageLoadingProgress.show()
}
}
......@@ -89,28 +89,28 @@ internal class PdfViewAdapter(
renderer?.renderPage(adapterPosition) { bitmap: Bitmap?, pageNo: Int ->
if (pageNo == adapterPosition) {
bitmap?.let {
itemView.container_view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
binding.containerView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height =
(itemView.container_view.width.toFloat() / ((bitmap.width.toFloat() / bitmap.height.toFloat()))).toInt()
(binding.containerView.width.toFloat() / ((bitmap.width.toFloat() / bitmap.height.toFloat()))).toInt()
this.topMargin = pageSpacing.top
this.leftMargin = pageSpacing.left
this.rightMargin = pageSpacing.right
this.bottomMargin = pageSpacing.bottom
}
itemView.pageView.setImageBitmap(bitmap)
itemView.pageView.animation = AlphaAnimation(0F, 1F).apply {
binding.pageView.setImageBitmap(bitmap)
binding.pageView.animation = AlphaAnimation(0F, 1F).apply {
interpolator = LinearInterpolator()
duration = 200
}
itemView.pdf_view_page_loading_progress.hide()
binding.include.pdfViewPageLoadingProgress.hide()
}
}
}
}
override fun onViewDetachedFromWindow(p0: View) {
itemView.pageView.setImageBitmap(null)
itemView.pageView.clearAnimation()
binding.pageView.setImageBitmap(null)
binding.pageView.clearAnimation()
}
}
......
......@@ -4,28 +4,22 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.webkit.MimeTypeMap
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.DefaultItemAnimator
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.blankj.utilcode.util.UriUtils
......@@ -34,23 +28,13 @@ import com.cherry.lib.doc.bean.DocEngine
import com.cherry.lib.doc.bean.DocMovingOrientation
import com.cherry.lib.doc.bean.DocSourceType
import com.cherry.lib.doc.bean.FileType
import com.cherry.lib.doc.interfaces.OnDownloadListener
import com.cherry.lib.doc.databinding.DocViewBinding
import com.cherry.lib.doc.interfaces.OnDocPageChangeListener
import com.cherry.lib.doc.interfaces.OnPdfItemClickListener
import com.cherry.lib.doc.interfaces.OnWebLoadListener
import com.cherry.lib.doc.office.IOffice
import com.cherry.lib.doc.pdf.PdfDownloader
import com.cherry.lib.doc.pdf.PdfPageViewAdapter
import com.cherry.lib.doc.pdf.PdfQuality
import com.cherry.lib.doc.pdf.PdfRendererCore
import com.cherry.lib.doc.pdf.PdfViewAdapter
import com.cherry.lib.doc.util.Constant
import com.cherry.lib.doc.util.FileUtils
import com.cherry.lib.doc.util.ViewUtils.hide
import com.cherry.lib.doc.util.ViewUtils.show
import kotlinx.android.synthetic.main.doc_view.view.*
import java.io.File
import java.net.URLEncoder
/*
* -----------------------------------------------------------------
......@@ -63,18 +47,14 @@ import java.net.URLEncoder
* -----------------------------------------------------------------
*/
class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClickListener {
class DocView : FrameLayout {
private val TAG = "DocView"
var mActivity: Activity? = null
var lifecycleScope: LifecycleCoroutineScope = (context as AppCompatActivity).lifecycleScope
private var mPoiViewer:PoiViewer? = null
private var pdfRendererCore: PdfRendererCore? = null
private var pdfViewAdapter: PdfViewAdapter? = null
private var pdfPageViewAdapter: PdfPageViewAdapter? = null
private var mPoiViewer: PoiViewer? = null
private var mMovingOrientation = DocMovingOrientation.HORIZONTAL
private var quality = PdfQuality.NORMAL
private var engine = DocEngine.INTERNAL
private var showDivider = true
private var showPageNum = true
......@@ -87,7 +67,7 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
var pbColor: Int = pbDefaultColor
private var pdfRendererCoreInitialised = false
var pageMargin: Rect = Rect(0,0,0,0)
var pageMargin: Rect = Rect(0, 0, 0, 0)
var totalPageCount = 0
......@@ -102,11 +82,13 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
initView(attrs, defStyle)
}
private lateinit var binding: DocViewBinding
fun initView(attrs: AttributeSet?, defStyle: Int) {
inflate(context, R.layout.doc_view, this)
mIvPdf.setOnClickListener {
mLlBigPdfImage.hide()
binding = DocViewBinding.bind(this)
binding.mIvPdf.setOnClickListener {
binding.mLlBigPdfImage.hide()
}
val typedArray =
......@@ -114,9 +96,6 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
val orientation =
typedArray.getInt(R.styleable.DocView_dv_moving_orientation, DocMovingOrientation.HORIZONTAL.orientation)
mMovingOrientation = DocMovingOrientation.values().first { it.orientation == orientation }
val ratio =
typedArray.getInt(R.styleable.DocView_dv_quality, PdfQuality.NORMAL.ratio)
quality = PdfQuality.values().first { it.ratio == ratio }
val engineValue =
typedArray.getInt(R.styleable.DocView_dv_engine, DocEngine.INTERNAL.value)
engine = DocEngine.values().first { it.value == engineValue }
......@@ -135,31 +114,33 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
bottom = typedArray.getDimensionPixelSize(R.styleable.DocView_dv_page_marginBottom, bottom)
}
var layoutParams = mPlLoadProgress.layoutParams
binding.mPdfPageNo.isVisible = showPageNum
val layoutParams = binding.mPlLoadProgress.layoutParams
layoutParams.height = pbHeight
mPlLoadProgress.layoutParams = layoutParams
binding.mPlLoadProgress.layoutParams = layoutParams
mPlLoadProgress.progressTintList = ColorStateList.valueOf(pbColor)
binding.mPlLoadProgress.progressTintList = ColorStateList.valueOf(pbColor)
typedArray.recycle()
runnable = Runnable {
mPdfPageNo.hide()
}
}
fun openDoc(activity: Activity, docUrl: String?, docSourceType: Int,
engine: DocEngine = this.engine) {
fun openDoc(
activity: Activity, docUrl: String?, docSourceType: Int,
engine: DocEngine = this.engine
) {
mActivity = activity
openDoc(activity, docUrl, docSourceType,-1,false,engine)
openDoc(activity, docUrl, docSourceType, -1, false, engine)
}
fun openDoc(activity: Activity?, docUrl: String?,
docSourceType: Int, fileType: Int,
viewPdfInPage: Boolean = false,
engine: DocEngine = this.engine) {
@SuppressLint("ObsoleteSdkInt")
fun openDoc(
activity: Activity?, docUrl: String?,
docSourceType: Int, fileType: Int,
viewPdfInPage: Boolean = false,
engine: DocEngine = this.engine
) {
var fileType = fileType
var docUrl = docUrl
var docSourceType = docSourceType
......@@ -184,7 +165,7 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
Log.d(TAG, "file = null")
}
}
Log.e(TAG,"openDoc()......fileType = $fileType")
Log.e(TAG, "openDoc()......fileType = $fileType")
mActivity = activity
mViewPdfInPage = viewPdfInPage
if (docSourceType == DocSourceType.PATH) {
......@@ -192,77 +173,54 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
} else {
sourceFilePath = null
}
if (docSourceType == DocSourceType.URL && fileType != FileType.IMAGE) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
|| engine == DocEngine.MICROSOFT
|| engine == DocEngine.XDOC
|| engine == DocEngine.GOOGLE) {
showByWeb(docUrl ?: "",engine)
return
}
downloadFile(docUrl ?: "")
return
}
var type = FileUtils.getFileTypeForUrl(docUrl)
if (fileType > 0) {
type = fileType
}
when (type) {
FileType.PDF -> {
Log.e(TAG,"openDoc()......PDF")
mDocWeb.hide()
mFlDocContainer.hide()
mRvPdf.show()
mIvImage.hide()
Log.e(TAG, "openDoc()......PDF")
// binding.mDocWeb.hide()
binding.mFlDocContainer.hide()
binding.mIvImage.hide()
showPdf(docSourceType,docUrl)
}
FileType.IMAGE -> {
if (showPageNum) {
showPageNum = false
}
Log.e(TAG,"openDoc()......")
mDocWeb.hide()
mFlDocContainer.hide()
mRvPdf.hide()
mIvImage.show()
Log.e(TAG, "openDoc()......")
// binding.mDocWeb.hide()
binding.mFlDocContainer.hide()
binding.mIvImage.show()
if (docSourceType == DocSourceType.PATH) {
Log.e(TAG,"openDoc()......PATH")
mIvImage.load(File(docUrl))
Log.e(TAG, "openDoc()......PATH")
binding.mIvImage.load(File(docUrl))
} else {
Log.e(TAG,"openDoc()......URL")
mIvImage.load(docUrl)
Log.e(TAG, "openDoc()......URL")
binding.mIvImage.load(docUrl)
}
}
FileType.NOT_SUPPORT -> {
if (showPageNum) {
showPageNum = false
}
Log.e(TAG,"openDoc()......NOT_SUPPORT")
mDocWeb.show()
mFlDocContainer.hide()
mRvPdf.hide()
mIvImage.hide()
showByWeb(docUrl ?: "",this.engine)
}
else -> {
Log.e(TAG,"openDoc()......ELSE")
Log.e(TAG, "openDoc()......ELSE")
if (showPageNum) {
showPageNum = false
}
mDocWeb.hide()
mFlDocContainer.show()
mRvPdf.hide()
mIvImage.hide()
activity?.let { showDoc(it,mFlDocContainer,docUrl,docSourceType,fileType) }
binding.mFlDocContainer.show()
binding.mIvImage.hide()
activity?.let { showDoc(it, binding.mFlDocContainer, docUrl, docSourceType, fileType) }
}
}
}
fun showDoc(activity: Activity, mDocContainer: ViewGroup?, url: String?, docSourceType: Int, fileType: Int) {
Log.e(TAG,"showDoc()......")
var iOffice: IOffice = object: IOffice() {
Log.e(TAG, "showDoc()......")
val iOffice: IOffice = object : IOffice() {
override fun getActivity(): Activity {
return activity
}
......@@ -277,7 +235,7 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
RelativeLayout.LayoutParams.MATCH_PARENT
)
)
},200)
}, 200)
}
override fun openFileFailed() {
......@@ -285,7 +243,9 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
if (mPoiViewer == null) {
mPoiViewer = PoiViewer(context)
}
mPoiViewer?.loadFile(mFlDocContainer, sourceFilePath)
mPoiViewer?.loadFile(
binding.mFlDocContainer, sourceFilePath
)
} catch (e: Exception) {
e.printStackTrace()
Toast.makeText(context, R.string.open_failed, Toast.LENGTH_SHORT).show()
......@@ -309,185 +269,28 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
}
}
iOffice.openFile(url,docSourceType, fileType.toString())
}
fun showPdf(docSourceType: Int, url: String?) {
Log.e(TAG,"showPdf()......quality = $quality")
when (docSourceType) {
DocSourceType.URL -> {
Log.e(TAG,"showPdf()......URL")
initWithUrl(url = url ?: "", pdfQuality = quality)
}
DocSourceType.URI -> {
Log.e(TAG,"showPdf()......URI")
initWithUri(fileUri = url ?: "", pdfQuality = quality)
}
DocSourceType.PATH -> {
Log.e(TAG,"showPdf()......PATH")
initWithPath(path = url ?: "", pdfQuality = quality)
}
DocSourceType.ASSETS -> {
Log.e(TAG,"showPdf()......ASSETS")
initWithAssets(fileName = url ?: "", pdfQuality = quality)
}
}
}
private fun showPdf(file: File, pdfQuality: PdfQuality) {
Log.e(javaClass.simpleName,"initView-exists = ${file.exists()}")
Log.e(javaClass.simpleName,"initView-mViewPdfInPage = $mViewPdfInPage")
pdfRendererCore = PdfRendererCore(context, file, pdfQuality)
totalPageCount = pdfRendererCore?.getPageCount() ?: 0
pdfRendererCoreInitialised = true
pdfViewAdapter = PdfViewAdapter(pdfRendererCore, pageMargin, enableLoadingForPages,this)
pdfPageViewAdapter = PdfPageViewAdapter(pdfRendererCore, pageMargin, enableLoadingForPages)
mRvPdf.setEnableScale(true)
if (mViewPdfInPage) {
mRvPdf.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
mRvPdf.adapter = pdfPageViewAdapter
PagerSnapHelper().attachToRecyclerView(mRvPdf)
} else {
mRvPdf.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
mRvPdf.adapter = pdfViewAdapter
}
mRvPdf.itemAnimator = DefaultItemAnimator()
mRvPdf.addOnScrollListener(scrollListener)
if (showDivider && !mViewPdfInPage) {
DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply {
divider?.let { setDrawable(it) }
}.let { mRvPdf.addItemDecoration(it) }
}
}
fun initWithUrl(
url: String,
pdfQuality: PdfQuality = this.quality,
engine: DocEngine = this.engine,
lifecycleScope: LifecycleCoroutineScope = (context as AppCompatActivity).lifecycleScope
) {
this.lifecycleScope = lifecycleScope
downloadFile(url, pdfQuality, lifecycleScope)
}
fun initWithPath(path: String, pdfQuality: PdfQuality = this.quality) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
throw UnsupportedOperationException("should be over API 21")
initWithFile(File(path), pdfQuality)
}
fun initWithFile(file: File, pdfQuality: PdfQuality = this.quality) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
throw UnsupportedOperationException("should be over API 21")
showPdf(file, pdfQuality)
}
fun initWithAssets(fileName: String, pdfQuality: PdfQuality = this.quality) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
throw UnsupportedOperationException("should be over API 21")
val file = FileUtils.fileFromAsset(context,fileName)
showPdf(file, pdfQuality)
}
fun initWithUri(fileUri: String, pdfQuality: PdfQuality = this.quality) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
throw UnsupportedOperationException("should be over API 21")
val file = FileUtils.fileFromUri(context,fileUri)
showPdf(file, pdfQuality)
}
fun downloadFile(url: String, pdfQuality: PdfQuality = this.quality,
lifecycleScope: LifecycleCoroutineScope = (context as AppCompatActivity).lifecycleScope) {
PdfDownloader(url, this)
}
@SuppressLint("SetJavaScriptEnabled")
private fun showByWeb(url: String,engine: DocEngine = this.engine) {
mDocWeb.mOnWebLoadListener = this
var engineUrl = "engine"
when (engine) {
DocEngine.MICROSOFT -> {
engineUrl = Constant.MICROSOFT_URL
}
DocEngine.XDOC -> {
engineUrl = Constant.XDOC_VIEW_URL
}
DocEngine.GOOGLE -> {
engineUrl = Constant.GOOGLE_URL
}
else -> {
engineUrl = Constant.XDOC_VIEW_URL
}
}
mDocWeb.loadUrl("$engineUrl${URLEncoder.encode(url, "UTF-8")}")
}
override fun getDownloadContext() = context
override fun onDownloadStart() {
Log.e(TAG,"initWithUrl-onDownloadStart()......")
}
override fun onDownloadProgress(currentBytes: Long, totalBytes: Long) {
var progress = (currentBytes.toFloat() / totalBytes.toFloat() * 100F).toInt()
if (progress >= 100) {
progress = 100
}
Log.e(TAG,"initWithUrl-onDownloadProgress()......progress = $progress")
showLoadingProgress(progress)
}
override fun onDownloadSuccess(absolutePath: String) {
Log.e(TAG,"initWithUrl-onDownloadSuccess()......")
showLoadingProgress(100)
sourceFilePath = absolutePath
openDoc(mActivity, absolutePath, DocSourceType.PATH,-1,mViewPdfInPage)
}
override fun onError(error: Throwable) {
error.printStackTrace()
Log.e(TAG,"initWithUrl-onError()......${error.localizedMessage}")
showLoadingProgress(100)
}
override fun getCoroutineScope() = lifecycleScope
override fun OnWebLoadProgress(progress: Int) {
showLoadingProgress(progress)
}
override fun onTitle(title: String?) {
//是否绘制页码
iOffice.isDrawPageNumber
iOffice.openFile(url, docSourceType, fileType.toString())
}
fun showLoadingProgress(progress: Int) {
if (progress == 100) {
mPlLoadProgress.hide()
} else {
mPlLoadProgress?.show()
mPlLoadProgress?.progress = progress
}
}
private val scrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
(recyclerView.layoutManager as LinearLayoutManager).run {
var foundPosition : Int = findLastCompletelyVisibleItemPosition()
var foundPosition: Int = findLastCompletelyVisibleItemPosition()
if (foundPosition != RecyclerView.NO_POSITION)
mPdfPageNo.text = context.getString(R.string.pdfView_page_no,foundPosition + 1,totalPageCount)
binding.mPdfPageNo.text = context.getString(R.string.pdfView_page_no, foundPosition + 1, totalPageCount)
if (showPageNum) {
mPdfPageNo.visibility = View.VISIBLE
binding.mPdfPageNo.visibility = View.VISIBLE
}
if (foundPosition == 0 && !mViewPdfInPage)
mPdfPageNo.postDelayed({
mPdfPageNo.visibility = GONE
binding.mPdfPageNo.postDelayed({
binding.mPdfPageNo.visibility = GONE
}, 3000)
if (foundPosition != RecyclerView.NO_POSITION) {
......@@ -504,10 +307,10 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (newState == RecyclerView.SCROLL_STATE_IDLE && !mViewPdfInPage) {
mPdfPageNo.postDelayed(runnable, 3000)
if (newState == RecyclerView.SCROLL_STATE_IDLE && !mViewPdfInPage) {
binding.mPdfPageNo.postDelayed(runnable, 3000)
} else {
mPdfPageNo.removeCallbacks(runnable)
binding.mPdfPageNo.removeCallbacks(runnable)
}
}
}
......@@ -517,33 +320,9 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
onDestroy()
}
fun closePdfRender() {
try {
if (pdfRendererCoreInitialised) {
pdfRendererCore?.closePdfRender()
pdfRendererCoreInitialised = false
}
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun OnPdfItemClick(position: Int) {
mLlBigPdfImage.show()
mPbBigLoading.show()
mIvPdf.setImageBitmap(null)
pdfRendererCore?.renderPage(position,PdfQuality.ENHANCED) { bitmap: Bitmap?, pageNo: Int ->
mPbBigLoading.hide()
mIvPdf.setImageBitmap(bitmap)
mIvPdf.reset()
mPdfPageNo.visibility = GONE
}
}
fun onDestroy() {
mPoiViewer?.recycle()
closePdfRender()
mOnDocPageChangeListener = null
}
}
\ No newline at end of file
package com.cherry.lib.doc.widget
import android.annotation.SuppressLint
import android.app.DownloadManager
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Environment
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.webkit.*
import androidx.constraintlayout.widget.ConstraintLayout
import com.cherry.lib.doc.R
import com.cherry.lib.doc.interfaces.OnWebLoadListener
import kotlinx.android.synthetic.main.doc_web_view.view.*
/*
* -----------------------------------------------------------------
* Copyright (C) 2018-2028, by Victor, All rights reserved.
* -----------------------------------------------------------------
* File: ProgressWebView
* Author: Victor
* Date: 2022/3/1 18:28
* Description:
* -----------------------------------------------------------------
*/
class DocWebView : ConstraintLayout, DownloadListener {
val TAG = "DocWebView"
var isLastLoadSuccess = false//是否成功加载完成过web,成功过后的网络异常 不改变web
var isError = false
var openLinkBySysBrowser = false//是否使用系统浏览器打开http链接
var mOnWebLoadListener: OnWebLoadListener? = null
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {
initView()
}
fun initView() {
LayoutInflater.from(context).inflate(R.layout.doc_web_view, this, true)
mDocView.webChromeClient = DocWebChromeClient()
mDocView.webViewClient = DocWebViewClient()
//设置可以支持缩放
mDocView.settings.setSupportZoom(true)
//设置出现缩放工具
mDocView.settings.builtInZoomControls = true
//设定缩放控件隐藏
mDocView.settings.displayZoomControls = true
//设置可在大视野范围内上下左右拖动,并且可以任意比例缩放
mDocView.settings.useWideViewPort = true
//设置默认加载的可视范围是大视野范围
mDocView.settings.loadWithOverviewMode = true
//自适应屏幕 SINGLE_COLUMN:把所有内容放大到webview等宽的一列中 NORMAL:正常显示不做任何渲染。NARROW_COLUMNS:可能的话让所有列的宽度不超过屏幕宽度
mDocView.settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
mDocView.settings.javaScriptEnabled = true
mDocView.settings.domStorageEnabled = true
mDocView.settings.allowFileAccess = true
mDocView.settings.allowFileAccessFromFileURLs = true
mDocView.settings.allowUniversalAccessFromFileURLs = true
mDocView.settings.cacheMode = WebSettings.LOAD_NO_CACHE
mDocView.setDownloadListener(this)
}
private fun setProgress(newProgress: Int) {
mOnWebLoadListener?.OnWebLoadProgress(newProgress)
}
/**
* 千万不要更改这个 "SSDJsBirdge" 注意!!!!!
*/
@SuppressLint("JavascriptInterface")
fun addJavascriptInterface(jsInterface: Any) {
mDocView.addJavascriptInterface(jsInterface, "SSDJsBirdge")
}
fun reload() {
isError = false
mDocView.reload()
}
fun loadUrl(url: String) {
isError = false
try {
mDocView.loadUrl(url)
} catch (e: Exception) {
e.printStackTrace()
}
}
fun loadData(htmlData: String) {
mDocView.loadData(htmlData, "text/html", "utf-8")
}
fun loadData(htmlData: String, secondLinkBySysBrowser: Boolean) {
openLinkBySysBrowser = secondLinkBySysBrowser
mDocView.loadData(htmlData, "text/html", "utf-8")
}
fun downloadFile(url: String?, contentDisposition: String?, mimeType: String?) {
val request = DownloadManager.Request(Uri.parse(url))
// 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库
request.allowScanningByMediaScanner()
// 设置通知的显示类型,下载进行时和完成后显示通知
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
// 设置通知栏的标题,如果不设置,默认使用文件名
request.setTitle("下载完成")
// 设置通知栏的描述
// request.setDescription("This is description");
// 允许在计费流量下下载
request.setAllowedOverMetered(true)
// 允许该记录在下载管理界面可见
request.setVisibleInDownloadsUi(true)
// 允许漫游时下载
request.setAllowedOverRoaming(true)
val fileName = URLUtil.guessFileName(url, contentDisposition, mimeType)
Log.e(TAG, "downloadFile()-fileName = $fileName")
request.setDestinationInExternalPublicDir(Environment.getExternalStorageDirectory().toString() + "/Download/", fileName)
val downloadManager = mDocView.context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
// 添加一个下载任务
val downloadId = downloadManager.enqueue(request)
}
override fun onDownloadStart(
url: String?,
userAgent: String?,
contentDisposition: String?,
mimeType: String?,
contentLength: Long
) {
Log.e(TAG, "onDownloadStart()......url = $url")
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(url)
context.startActivity(intent)
// downloadFile(url,contentDisposition,mimeType)
}
fun canGoBack(): Boolean {
val canGoBack = mDocView.canGoBack()
if (canGoBack) {
mDocView.goBack()
}
return canGoBack
}
fun onPause() {
mDocView.pauseTimers()
}
fun onResume() {
mDocView.resumeTimers()
}
/**
* must be called on the main thread
*/
fun onDestroy() {
try {
mDocView.clearHistory();
mDocView.clearCache(true)
mDocView.loadUrl("about:blank") // clearView() should be changed to loadUrl("about:blank"), since clearView() is deprecated now
mDocView.freeMemory()
mDocView.pauseTimers()
mDocView.destroy() // Note that mWebView.destroy() and mWebView = null do the exact same thing
} catch (e: Exception) {
e.printStackTrace()
}
}
fun setWebViewBackgroundColor(isBlack: Boolean) {
if (isBlack) {
//防止加载html白屏(针对播放视频)
setBackgroundColor(Color.BLACK)
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
onDestroy()
}
private inner class DocWebChromeClient : WebChromeClient() {
override fun onProgressChanged(view: WebView, newProgress: Int) {
super.onProgressChanged(view, newProgress)
setProgress(newProgress)
}
override fun onReceivedTitle(view: WebView, title: String) {
super.onReceivedTitle(view, title)
if (title.contains("html")) {
return
}
mOnWebLoadListener?.onTitle(title)
}
}
private inner class DocWebViewClient : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
//在访问失败的时候会首先回调onReceivedError,然后再回调onPageFinished。
if (!isError) {
isLastLoadSuccess = true
mOnWebLoadListener?.OnWebLoadProgress(100)
}
}
override fun onReceivedError(view: WebView, request: WebResourceRequest, error: WebResourceError) {
super.onReceivedError(view, request, error)
//在访问失败的时候会首先回调onReceivedError,然后再回调onPageFinished。
isError = true
if (!isLastLoadSuccess) {//之前成功加载完成过,不会回调
mOnWebLoadListener?.OnWebLoadProgress(100)
}
}
}
}
\ No newline at end of file
......@@ -27,7 +27,7 @@ import java.util.*
* -----------------------------------------------------------------
*/
class PinchImageView: AppCompatImageView {
class PinchImageView : AppCompatImageView {
companion object {
////////////////////////////////配置参数////////////////////////////////
/**
......@@ -557,14 +557,15 @@ class PinchImageView: AppCompatImageView {
}
////////////////////////////////初始化////////////////////////////////
constructor(context: Context) :super(context) {
constructor(context: Context) : super(context) {
initView()
}
constructor(context: Context,attrs: AttributeSet?) :super(context,attrs) {
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
initView()
}
constructor(context: Context, attrs: AttributeSet?, defStyle: Int): super(context, attrs, defStyle) {
constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {
initView()
}
......@@ -742,38 +743,39 @@ class PinchImageView: AppCompatImageView {
*
* 在onTouchEvent末尾被执行.
*/
private val mGestureDetector = GestureDetector(this@PinchImageView.getContext(), object : SimpleOnGestureListener() {
override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
//只有在单指模式结束之后才允许执行fling
if (mPinchMode == PINCH_MODE_FREE && !(mScaleAnimator != null && mScaleAnimator!!.isRunning)) {
fling(velocityX, velocityY)
private val mGestureDetector = GestureDetector(this@PinchImageView.context,
object : SimpleOnGestureListener() {
override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
//只有在单指模式结束之后才允许执行fling
if (mPinchMode == PINCH_MODE_FREE && !(mScaleAnimator != null && mScaleAnimator!!.isRunning)) {
fling(velocityX, velocityY)
}
return true
}
return true
}
override fun onLongPress(e: MotionEvent) {
//触发长按
if (mOnLongClickListener != null) {
mOnLongClickListener!!.onLongClick(this@PinchImageView)
override fun onLongPress(e: MotionEvent) {
//触发长按
if (mOnLongClickListener != null) {
mOnLongClickListener!!.onLongClick(this@PinchImageView)
}
}
}
override fun onDoubleTap(e: MotionEvent): Boolean {
//当手指快速第二次按下触发,此时必须是单指模式才允许执行doubleTap
if (mPinchMode == PINCH_MODE_SCROLL && !(mScaleAnimator != null && mScaleAnimator!!.isRunning)) {
doubleTap(e.x, e.y)
override fun onDoubleTap(e: MotionEvent): Boolean {
//当手指快速第二次按下触发,此时必须是单指模式才允许执行doubleTap
if (mPinchMode == PINCH_MODE_SCROLL && !(mScaleAnimator != null && mScaleAnimator!!.isRunning)) {
doubleTap(e.x, e.y)
}
return true
}
return true
}
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
//触发点击
if (mOnClickListener != null) {
mOnClickListener!!.onClick(this@PinchImageView)
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
//触发点击
if (mOnClickListener != null) {
mOnClickListener!!.onClick(this@PinchImageView)
}
return true
}
return true
}
})
})
override fun onTouchEvent(event: MotionEvent): Boolean {
super.onTouchEvent(event)
......@@ -1220,7 +1222,11 @@ class PinchImageView: AppCompatImageView {
*
* 在给定时间内从一个矩阵的变化逐渐动画到另一个矩阵的变化
*/
private inner class ScaleAnimator @JvmOverloads constructor(start: Matrix, end: Matrix, duration: Long = SCALE_ANIMATOR_DURATION.toLong()) : ValueAnimator(), AnimatorUpdateListener {
private inner class ScaleAnimator @JvmOverloads constructor(
start: Matrix,
end: Matrix,
duration: Long = SCALE_ANIMATOR_DURATION.toLong()
) : ValueAnimator(), AnimatorUpdateListener {
/**
* 开始矩阵
*/
......@@ -1284,10 +1290,11 @@ class PinchImageView: AppCompatImageView {
* @param <T> 对象池容纳的对象类型
</T> */
private abstract class ObjectsPool<T>(
/**
* 对象池的最大容量
*/
private val mSize: Int) {
/**
* 对象池的最大容量
*/
private val mSize: Int
) {
/**
* 对象池队列
......
package com.cherry.lib.doc.widget;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.ContextWrapper;
......@@ -41,6 +42,7 @@ public class PoiViewer {
initCacheDir();
}
@SuppressLint("SetJavaScriptEnabled")
private void initView() {
mProgressDialog = new ProgressDialog(mContext);
mProgressDialog.setMessage("正在加载文件...");
......
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<com.cherry.lib.doc.pdf.PinchZoomRecyclerView
android:id="@+id/mRvPdf"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:scrollbars="vertical"
tools:listitem="@layout/list_item_pdf" />
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/mLlBigPdfImage"
......@@ -23,15 +14,15 @@
<com.cherry.lib.doc.widget.PinchImageView
android:id="@+id/mIvPdf"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent" />
<ProgressBar
android:id="@+id/mPbBigLoading"
android:layout_gravity="center"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:visibility="gone"
tools:visibility="visible"/>
tools:visibility="visible" />
<ImageView
android:layout_width="wrap_content"
......@@ -40,33 +31,29 @@
android:layout_marginTop="50dp"
android:layout_marginEnd="30dp"
android:scaleType="fitCenter"
android:src="@mipmap/ic_big_close"/>
android:src="@mipmap/ic_big_close"
tools:ignore="ContentDescription" />
</FrameLayout>
<FrameLayout
android:id="@+id/mFlDocContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent" />
<com.cherry.lib.doc.widget.PinchImageView
android:id="@+id/mIvImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"/>
<com.cherry.lib.doc.widget.DocWebView
android:id="@+id/mDocWeb"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:scaleType="fitCenter" />
<ProgressBar
android:id="@+id/mPlLoadProgress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="20dp"
style="?android:attr/progressBarStyleHorizontal"
android:progressDrawable="@drawable/pb_webview_layer"
android:visibility="visible"/>
android:visibility="visible" />
<TextView
android:id="@+id/mPdfPageNo"
......@@ -79,7 +66,6 @@
android:paddingEnd="12dp"
android:paddingBottom="4dp"
android:textColor="#A19D9D"
android:textSize="16sp"
android:visibility="gone" />
android:textSize="16sp" />
</FrameLayout>
\ No newline at end of file
......@@ -14,6 +14,8 @@
android:padding="0dp"
android:scaleType="fitCenter" />
<include layout="@layout/pdf_view_page_loading_layout" />
<include
android:id="@+id/include"
layout="@layout/pdf_view_page_loading_layout" />
</FrameLayout>
\ No newline at end of file
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