在我的Android活动中,我使用的RecyclerView
包含MathViews
个数字。 MathView
是显示LaTeX内容的第三方库(This
有点类似WebView
。在这个android项目中可以看到MathView
的实现。 github.com/lingarajsankaravelu/Katex)。
问题是,为了呈现此MathView
的内容,需要更长的时间。由于我在MathView
中使用了少量RecycleView
个组件,因此渲染时间会增加更多。因此,当Activity开始时,首先在视图中显示一些空白区域几秒钟,然后呈现相关内容。
作为此问题的解决方案,我需要显示一个进度条,直到完全呈现Activity的所有布局内容,并在渲染完成后显示Activity。
相关源代码如下所示。
MathView;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:auto="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:id="@+id/equation_item"
android:clickable="true"
android:foreground="?attr/selectableItemBackground">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="4dp">
<katex.hourglass.in.mathlib.MathView
android:id="@+id/math_view"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="left"
app:setClickable="true"
app:setTextColor="@color/colorPrimary"
app:setTextSize="10sp"
/>
</android.support.v7.widget.CardView>
<include layout="@layout/item_divider"/>
</LinearLayout>
Recycler View;
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.a37moons.mathcheatsheets.ContentActivity"
tools:showIn="@layout/activity_content">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view_equations"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.NestedScrollView>
ViewHolder Class
public class ViewHolder extends RecyclerView.ViewHolder {
public MathView mathView;
public ViewHolder(View itemView) {
super(itemView);
mathView = itemView.findViewById(R.id.math_view);
}
}
Recycler Adapter Class
public class RecyclerAdapterEquations extends RecyclerView.Adapter<ViewHolder>{
private List<Equation> equations;
View view;
public RecyclerAdapterEquations(List<Equation> equations){
this.equations = equations;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.equation_view_item,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Equation sampleEquation = equations.get(position);
holder.mathView.setDisplayText(sampleEquation.equationString);
// holder.mathView2.setText(sampleEquation.equationString);
Log.d("MATH_APP","position "+position+" mathview text set ");
}
@Override
public int getItemCount() {
return equations.size();
}
}
最后实施。
RecyclerView recyclerView;
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(new RecyclerAdapterEquations(sample));
答案 0 :(得分:5)
借助azizbekian所写的答案,我找到了问题的答案。
如answer所述,这是程序;
- 在xml文件中引入
之上绘制ProgressBar
或类似内容。此视图应在RecyclerView
之后声明 在RecyclerView
- 让
RecyclerView
隐身(通过android:visibility="invisible"
)- 现在
醇>RecyclerView
实际上已经布置但未在屏幕上显示。你需要一个回调,这将被执行一段时间 稍后设置RecyclerView
时。在你的回调中 将隐藏进度条并将RecyclerView
的可见性更改为View.VISIBLE
。
现在由于katex.hourglass.in.mathlib.MathView
是android WebView
的子类,我们可以为此设置WebChromeClient
。然后,我们可以获得加载内容的进度百分比。
int loadedPercentage = 0;
boolean loaded = false;
mathView.setWebChromeClient(new WebChromeClient(){
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
loadedPercentage = newProgress;
if(newProgress==100) {
//When the loading is 100% completed; todo
loaded = true;
Toast.makeText(getContext(), newProgress + "LOADED COMPLETELY", Toast.LENGTH_SHORT).show();
}
}
});
我们可以实施进度条来显示loadedPercentage
。当loadedPercentage
为100时,我们可以看到相关内容已完全加载。
所以我编辑了MathView
类如下;
public class MyMathView extends WebView {
private String TAG = "KhanAcademyKatexView";
private static final float default_text_size = 18;
private String display_text;
private int text_color;
private int text_size;
private boolean clickable = false;
private boolean loaded = false;
private int loadedPercentage = 0;
public MyMathView(Context context) {
//...
}
public MyMathView(Context context, AttributeSet attrs) {
//...
}
public boolean isLoaded(){
return loaded;
}
public int getLoadedPercentage() {
return loadedPercentage;
}
public void setViewBackgroundColor(int color)
{
//...
}
private void pixelSizeConversion(float dimension) {
//...
}
private void configurationSettingWebView()
{
//...
}
public void setDisplayText(String formula_text) {
this.display_text = formula_text;
loadData();
}
private String getOfflineKatexConfig()
{
String offline_config = "<!DOCTYPE html>\n" +
"<html>\n" +
" <head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <title>Auto-render test</title>\n" +
" <link rel=\"stylesheet\" type=\"text/css\" href=\"file:///android_asset/katex/katex.min.css\">\n" +
" <link rel=\"stylesheet\" type=\"text/css\" href=\"file:///android_asset/themes/style.css\">\n" +
" <script type=\"text/javascript\" src=\"file:///android_asset/katex/katex.min.js\"></script>\n" +
" <script type=\"text/javascript\" src=\"file:///android_asset/katex/contrib/auto-render.min.js\"></script>\n" +
" <style type='text/css'>"+
"body {"+
"margin: 0px;"+
"padding: 0px;"+
"font-size:" +this.text_size+"px;"+
"color:"+getHexColor(this.text_color)+";"+
" }"+
" </style>"+
" </head>\n" +
" <body>\n" +
" {formula}\n" +
" <script>\n" +
" renderMathInElement(\n" +
" document.body\n" +
" );\n" +
" </script>\n" +
" </body>\n" +
"</html>";
String start = "<html><head><meta http-equiv='Content-Type' content='text/html' charset='UTF-8' /><style> body {"+
" white-space: nowrap;}</style></head><body>";
String end = "</body></html>";
//return start+offline_config.replace("{formula}",this.display_text)+end;
return offline_config.replace("{formula}",this.display_text);
}
private void loadData()
{
if (this.display_text!=null)
{
loadedPercentage = 0;
loaded = false;
this.setWebChromeClient(new WebChromeClient(){
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
loadedPercentage = newProgress;
if(newProgress==100) {
loaded = true;
Toast.makeText(getContext(), newProgress + "LOADED", Toast.LENGTH_SHORT).show();
}
}
});
this.loadDataWithBaseURL("null",getOfflineKatexConfig(),"text/html","UTF-8","about:blank");
}
}
public void setTextSize(int size)
{
//...
}
public void setTextColor(int color)
{
//...
}
private String getHexColor(int intColor)
{
//...
}
private void setDefaultTextColor(Context context) {
//...
}
private void setDefaultTextSize() {
//...
}
}
答案 1 :(得分:3)
我无法在说明中看到问题本身,因此我将参考your statement in comments section:
我只需要一个解决方案来显示进度条,直到
Activity
的所有布局内容完全呈现,然后在渲染完成后,显示Activity
。
ProgressBar
或类似内容。应在RecyclerView
之后声明此视图,以便在RecyclerView
RecyclerView
隐身(通过android:visibility="invisible"
)RecyclerView
实际上已经布置但未在屏幕上显示。您需要一个回调,该回调将在稍后设置RecyclerView
时执行。在此回调中,您将隐藏进度条并将RecyclerView
的可见性更改为View.VISIBLE
。问题在于附加&#34; RecyclerView
的孩子已初始化&#34; 听众。
只要katex.hourglass.in.mathlib.MathView
是android.webkit.WebView
的子类,这意味着,为了获得有关加载完成事件的通知,您应该按以下方法注册WebViewClient
:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Equation sampleEquation = equations.get(position);
holder.mathView.setDisplayText(sampleEquation.equationString);
holder.mathView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// No longer interested in upcoming events - unregister
view.setWebViewClient(null);
// Now data is loaded, can make RecyclerView visible
}
});
...
}
请注意,只要加载了RecyclerView
,就会显示MathView
。您可以根据需要等待所有这些加载。
答案 2 :(得分:0)
不要打电话
console.log(`User created ${user}`);
像往常一样,首先在适配器中加载数据,然后调用
setContentView(layout);
之后将适配器设置为recyclerview。