猿问
下载APP

Android中的分页文本

Android中的分页文本

我正在为Android编写一个简单的文本/电子书查看器,因此我使用了TextView向用户显示HTML格式的文本,因此他们可以通过来回浏览页面中的文本。但我的问题是我不能在Android中对文本进行分页。

我不能(或者我不知道如何)从断行和分页算法中获得适当的反馈,其中TextView用于将文本分成行和页面。因此,我无法理解内容在实际显示中的结束位置,以便我继续从下一页的剩余部分开始。我想找到克服这个问题的方法。

如果我知道屏幕上绘制的最后一个字符是什么,我可以轻松地填充足够的字符来填充屏幕,并且知道实际绘画的完成位置,我可以继续下一页。这可能吗?怎么样?


largeQ
浏览 25回答 3
3回答

慕雪6173905

背景我们对文本处理的了解TextView是,它根据视图的宽度按行正确地分解文本。查看TextView的源代码,我们可以看到文本处理是由Layout类完成的。因此,我们可以利用Layout班级为我们所做的工作,并利用其方法进行分页。问题问题TextView在于文本的可见部分可能会在最后一条可见线的中间某处垂直切割。关于上述,我们应该在满足视图高度的最后一行时打破一个新页面。算法我们遍历文本行并检查线条是否bottom超出视图的高度;如果是这样,我们打破一个新页面并计算累积高度的新值,以比较以下几行bottom(参见实现)。新值定义为不适合上一页+&nbsp;高度的行的top值(下图中的红线)TextView's。履行public&nbsp;class&nbsp;Pagination&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;final&nbsp;boolean&nbsp;mIncludePad; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;final&nbsp;int&nbsp;mWidth; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;final&nbsp;int&nbsp;mHeight; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;final&nbsp;float&nbsp;mSpacingMult; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;final&nbsp;float&nbsp;mSpacingAdd; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;final&nbsp;CharSequence&nbsp;mText; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;final&nbsp;TextPaint&nbsp;mPaint; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;final&nbsp;List<CharSequence>&nbsp;mPages; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Pagination(CharSequence&nbsp;text,&nbsp;int&nbsp;pageW,&nbsp;int&nbsp;pageH,&nbsp;TextPaint&nbsp;paint,&nbsp;float&nbsp;spacingMult,&nbsp;float&nbsp;spacingAdd,&nbsp;boolean&nbsp;inclidePad)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.mText&nbsp;=&nbsp;text; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.mWidth&nbsp;=&nbsp;pageW; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.mHeight&nbsp;=&nbsp;pageH; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.mPaint&nbsp;=&nbsp;paint; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.mSpacingMult&nbsp;=&nbsp;spacingMult; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.mSpacingAdd&nbsp;=&nbsp;spacingAdd; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.mIncludePad&nbsp;=&nbsp;inclidePad; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.mPages&nbsp;=&nbsp;new&nbsp;ArrayList<>(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;layout(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;layout()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;final&nbsp;StaticLayout&nbsp;layout&nbsp;=&nbsp;new&nbsp;StaticLayout(mText,&nbsp;mPaint,&nbsp;mWidth,&nbsp;Layout.Alignment.ALIGN_NORMAL,&nbsp;mSpacingMult,&nbsp;mSpacingAdd,&nbsp;mIncludePad); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;final&nbsp;int&nbsp;lines&nbsp;=&nbsp;layout.getLineCount(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;final&nbsp;CharSequence&nbsp;text&nbsp;=&nbsp;layout.getText(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;startOffset&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;height&nbsp;=&nbsp;mHeight; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;lines;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(height&nbsp;<&nbsp;layout.getLineBottom(i))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;When&nbsp;the&nbsp;layout&nbsp;height&nbsp;has&nbsp;been&nbsp;exceeded &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addPage(text.subSequence(startOffset,&nbsp;layout.getLineStart(i))); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;startOffset&nbsp;=&nbsp;layout.getLineStart(i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height&nbsp;=&nbsp;layout.getLineTop(i)&nbsp;+&nbsp;mHeight; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i&nbsp;==&nbsp;lines&nbsp;-&nbsp;1)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Put&nbsp;the&nbsp;rest&nbsp;of&nbsp;the&nbsp;text&nbsp;into&nbsp;the&nbsp;last&nbsp;page &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addPage(text.subSequence(startOffset,&nbsp;layout.getLineEnd(i))); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;addPage(CharSequence&nbsp;text)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mPages.add(text); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;size()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;mPages.size(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;CharSequence&nbsp;get(int&nbsp;index)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(index&nbsp;>=&nbsp;0&nbsp;&&&nbsp;index&nbsp;<&nbsp;mPages.size())&nbsp;?&nbsp;mPages.get(index)&nbsp;:&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;}}注1该算法不仅适用于TextView(Pagination类使用TextView's上面实现中的参数)。您可以通过任何一组参数StaticLayout接受,后来使用分页布局上绘制文本Canvas/&nbsp;Bitmap/&nbsp;PdfDocument。您还可以将不同字体和格式化字符串Spannable用作yourText参数Html(如下面的示例所示)。笔记2当所有文本具有相同的字体大小时,所有行都具有相同的高度。在这种情况下,您可能需要考虑通过计算适合单个页面的行数并在每次循环迭代时跳转到正确的行来进一步优化算法。样品下面的示例分页包含两者html和Spanned文本的字符串。public&nbsp;class&nbsp;PaginationActivity&nbsp;extends&nbsp;Activity&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;TextView&nbsp;mTextView; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Pagination&nbsp;mPagination; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;CharSequence&nbsp;mText; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;int&nbsp;mCurrentIndex&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;onCreate(Bundle&nbsp;savedInstanceState)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super.onCreate(savedInstanceState); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setContentView(R.layout.activity_pagination); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mTextView&nbsp;=&nbsp;(TextView)&nbsp;findViewById(R.id.tv); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Spanned&nbsp;htmlString&nbsp;=&nbsp;Html.fromHtml(getString(R.string.html_string)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Spannable&nbsp;spanString&nbsp;=&nbsp;new&nbsp;SpannableString(getString(R.string.long_string)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spanString.setSpan(new&nbsp;ForegroundColorSpan(Color.BLUE),&nbsp;0,&nbsp;24,&nbsp;Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spanString.setSpan(new&nbsp;RelativeSizeSpan(2f),&nbsp;0,&nbsp;24,&nbsp;Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spanString.setSpan(new&nbsp;StyleSpan(Typeface.MONOSPACE.getStyle()),&nbsp;0,&nbsp;24,&nbsp;Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spanString.setSpan(new&nbsp;ForegroundColorSpan(Color.BLUE),&nbsp;700,&nbsp;spanString.length(),&nbsp;Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spanString.setSpan(new&nbsp;RelativeSizeSpan(2f),&nbsp;700,&nbsp;spanString.length(),&nbsp;Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spanString.setSpan(new&nbsp;StyleSpan(Typeface.MONOSPACE.getStyle()),&nbsp;700,&nbsp;spanString.length(),&nbsp;Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mText&nbsp;=&nbsp;TextUtils.concat(htmlString,&nbsp;spanString); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mTextView.getViewTreeObserver().addOnGlobalLayoutListener(new&nbsp;ViewTreeObserver.OnGlobalLayoutListener()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onGlobalLayout()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Removing&nbsp;layout&nbsp;listener&nbsp;to&nbsp;avoid&nbsp;multiple&nbsp;calls &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mTextView.getViewTreeObserver().removeOnGlobalLayoutListener(this); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mPagination&nbsp;=&nbsp;new&nbsp;Pagination(mText, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mTextView.getWidth(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mTextView.getHeight(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mTextView.getPaint(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mTextView.getLineSpacingMultiplier(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mTextView.getLineSpacingExtra(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mTextView.getIncludeFontPadding()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;findViewById(R.id.btn_back).setOnClickListener(v&nbsp;->&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mCurrentIndex&nbsp;=&nbsp;(mCurrentIndex&nbsp;>&nbsp;0)&nbsp;?&nbsp;mCurrentIndex&nbsp;-&nbsp;1&nbsp;:&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;findViewById(R.id.btn_forward).setOnClickListener(v&nbsp;->&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mCurrentIndex&nbsp;=&nbsp;(mCurrentIndex&nbsp;<&nbsp;mPagination.size()&nbsp;-&nbsp;1)&nbsp;?&nbsp;mCurrentIndex&nbsp;+&nbsp;1&nbsp;:&nbsp;mPagination.size()&nbsp;-&nbsp;1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;update()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;final&nbsp;CharSequence&nbsp;text&nbsp;=&nbsp;mPagination.get(mCurrentIndex); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(text&nbsp;!=&nbsp;null)&nbsp;mTextView.setText(text); &nbsp;&nbsp;&nbsp;&nbsp;}}Activity的布局:<RelativeLayout&nbsp;xmlns:android="http://schemas.android.com/apk/res/android" &nbsp;&nbsp;&nbsp;&nbsp;android:layout_width="match_parent" &nbsp;&nbsp;&nbsp;&nbsp;android:layout_height="match_parent" &nbsp;&nbsp;&nbsp;&nbsp;android:paddingLeft="@dimen/activity_horizontal_margin" &nbsp;&nbsp;&nbsp;&nbsp;android:paddingRight="@dimen/activity_horizontal_margin" &nbsp;&nbsp;&nbsp;&nbsp;android:paddingTop="@dimen/activity_vertical_margin" &nbsp;&nbsp;&nbsp;&nbsp;android:paddingBottom="@dimen/activity_vertical_margin"&nbsp;> &nbsp;&nbsp;&nbsp;&nbsp;<LinearLayout &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:layout_width="match_parent" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:layout_height="match_parent"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<Button &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:id="@+id/btn_back" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:layout_width="0dp" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:layout_height="match_parent" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:layout_weight="1" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:background="@android:color/transparent"/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<Button &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:id="@+id/btn_forward" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:layout_width="0dp" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:layout_height="match_parent" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:layout_weight="1" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:background="@android:color/transparent"/> &nbsp;&nbsp;&nbsp;&nbsp;</LinearLayout> &nbsp;&nbsp;&nbsp;&nbsp;<TextView &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:id="@+id/tv" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:layout_width="match_parent" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;android:layout_height="match_parent"/></RelativeLayout>

弑天下

看看我的演示项目。“魔术”在这段代码中:&nbsp;&nbsp;&nbsp;&nbsp;mTextView.setText(mText); &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;height&nbsp;=&nbsp;mTextView.getHeight(); &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;scrollY&nbsp;=&nbsp;mTextView.getScrollY(); &nbsp;&nbsp;&nbsp;&nbsp;Layout&nbsp;layout&nbsp;=&nbsp;mTextView.getLayout(); &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;firstVisibleLineNumber&nbsp;=&nbsp;layout.getLineForVertical(scrollY); &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;lastVisibleLineNumber&nbsp;=&nbsp;layout.getLineForVertical(height&nbsp;+&nbsp;scrollY); &nbsp;&nbsp;&nbsp;&nbsp;//check&nbsp;is&nbsp;latest&nbsp;line&nbsp;fully&nbsp;visible &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(mTextView.getHeight()&nbsp;<&nbsp;layout.getLineBottom(lastVisibleLineNumber))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lastVisibleLineNumber--; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;start&nbsp;=&nbsp;pageStartSymbol&nbsp;+&nbsp;mTextView.getLayout().getLineStart(firstVisibleLineNumber); &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;end&nbsp;=&nbsp;pageStartSymbol&nbsp;+&nbsp;mTextView.getLayout().getLineEnd(lastVisibleLineNumber); &nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;displayedText&nbsp;=&nbsp;mText.substring(start,&nbsp;end); &nbsp;&nbsp;&nbsp;&nbsp;//correct&nbsp;visible&nbsp;text &nbsp;&nbsp;&nbsp;&nbsp;mTextView.setText(displayedText);

慕侠2389804

令人惊讶的是,找到用于分页的库是困难的。我认为除TextView之外使用另一个Android UI元素会更好。WebView怎么样?一个例子@&nbsp;android-webview-example。代码段:webView&nbsp;=&nbsp;(WebView)&nbsp;findViewById(R.id.webView1);String&nbsp;customHtml&nbsp;=&nbsp;"<html><body><h1>Hello,&nbsp;WebView</h1></body></html>";webView.loadData(customHtml,&nbsp;"text/html",&nbsp;"UTF-8");注意:这只是将数据加载到WebView上,类似于Web浏览器。但是,让我们不要仅仅停留在这个想法上。将此UI添加到WebViewClient onPageFinished使用分页。请阅读SO链接@&nbsp;html-book-like-pagination。Dan的最佳答案之一的代码片段:mWebView.setWebViewClient(new&nbsp;WebViewClient()&nbsp;{ &nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onPageFinished(WebView&nbsp;view,&nbsp;String&nbsp;url)&nbsp;{ &nbsp;&nbsp;&nbsp;... &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mWebView.loadUrl("..."); &nbsp;&nbsp;&nbsp;}});笔记:代码在页面滚动时加载更多数据。在同一网页上,Engin Kurutepe发布了一个答案,用于设置WebView的测量值。这对于在分页中指定页面是必要的。我没有实现分页,但我认为这是一个良好的开端并显示出承诺,应该是快速的。如您所见,有些开发人员已实现此功能。
打开App,查看更多内容
随时随地看视频慕课网APP
我要回答