我试图使用DialogFragment显示我的Android应用程序的一些许可信息,该DialogFragment包含一个包含在ScrollView内部的TextView。具体而言,我正在使用从GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo()方法生成的String。这里生成的字符串包含大量文本,当我将所需信息传递给要显示的对话框时,UI线程会在最终显示对话框之前冻结约3-4秒。是否有更有效的方法在DialogFragment中显示大量文本?
以下是实例化和显示Dialog的代码。
if(googlePlayServicesLicense != null) {
// Google Play Service License Info
TitleParagraphViewModel googlePlayInfo =
new TitleParagraphViewModel("Google Play Services",
googlePlayServicesLicense);
infoList.add(googlePlayInfo);
}
// Create license dialog and show
TitleParagraphListDialog dialog =
TitleParagraphListDialog.newInstance("Licenses", infoList);
// Show the dialog
dialog.show(getSupportFragmentManager(), "dialog");
这是我的DialogFragment
的代码public class TitleParagraphListDialog extends DialogFragment {
private static final String DIALOG_TITLE_EXTRA_KEY = "dialog_title";
private static final String DIALOG_INFO_LIST_EXTRA_KEY = "info_list";
private String mDialogTitle;
private ArrayList<TitleParagraphViewModel> mInfoList;
private TextView mInformation;
public static TitleParagraphListDialog newInstance(String title, ArrayList<TitleParagraphViewModel> infoList) {
TitleParagraphListDialog dialog = new TitleParagraphListDialog();
Bundle args = new Bundle();
args.putString(DIALOG_TITLE_EXTRA_KEY, title);
args.putParcelableArrayList(DIALOG_INFO_LIST_EXTRA_KEY, infoList);
dialog.setArguments(args);
return dialog;
}
@SuppressWarnings("unchecked")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
mDialogTitle = args.getString(DIALOG_TITLE_EXTRA_KEY) != null ? args.getString(DIALOG_TITLE_EXTRA_KEY) : "Information";
mInfoList = (ArrayList<TitleParagraphViewModel>) (args.getParcelableArrayList(DIALOG_INFO_LIST_EXTRA_KEY) != null ? args.getParcelableArrayList(DIALOG_INFO_LIST_EXTRA_KEY) : new ArrayList<TitleParagraphViewModel>());
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View dialogView = inflater.inflate(R.layout.title_paragraph_dialog, null);
TextView dialogTitle = (TextView) dialogView.findViewById(R.id.dialog_title);
mInformation = (TextView) dialogView.findViewById(R.id.information);
dialogTitle.setText(mDialogTitle);
dialogTitle.setTypeface(Typeface.createFromAsset(getActivity()
.getAssets(), "fonts/Roboto-Light.ttf"));
mInformation.setTypeface(Typeface.createFromAsset(getActivity()
.getAssets(), "fonts/Roboto-Light.ttf"));
for(TitleParagraphViewModel info : mInfoList) {
mInformation.append(Html.fromHtml("<b>" + info.getTitle() + "</b>")
+ "\n\n" + info.getParagraph() + "\n\n");
}
builder.setView(dialogView)
.setPositiveButton("Done", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
TitleParagraphListDialog.this.getDialog().cancel();
}
});
return builder.create();
}
}
我想知道处理显示大量文本的更好方法。我尝试使用ListView,但性能更差。 GooglePlayServices许可证只是我可能需要在我的应用中显示的许多许可证之一。
如果您想知道TitleParagraphViewModel这里是它的代码。
public class TitleParagraphViewModel implements Parcelable {
private String title, paragraph;
public TitleParagraphViewModel(String title, String paragraph) {
this.title = title;
this.paragraph = paragraph;
}
public void setTitle(String title) {
this.title = title;
}
public void setParagraph(String paragraph) {
this.paragraph = paragraph;
}
public String getTitle() {
return this.title;
}
public String getParagraph() {
return this.paragraph;
}
// Parceling Part
public TitleParagraphViewModel(Parcel in) {
readFromParcel(in);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] { this.getTitle(), this.getParagraph()});
}
private void readFromParcel(Parcel in) {
String[] stringData = new String[2];
in.readStringArray(stringData);
this.setTitle(stringData[0]);
this.setParagraph(stringData[1]);
}
@SuppressWarnings("rawtypes")
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public Object createFromParcel(Parcel in) {
return new TitleParagraphViewModel(in);
}
@Override
public Object[] newArray(int size) {
return new Object[size];
}
};
}
答案 0 :(得分:2)
我最终将长文本拆分为一系列单独的行,然后使用appcompat&#39; s RecyclerView来显示该行数组。
以下是代码:
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
import com.google.android.gms.common.GoogleApiAvailability;
public class GoogleLicenseDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Activity activity = getActivity();
AlertDialog.Builder builder = new AlertDialog.Builder(activity)
.setPositiveButton(R.string.button_close, null);
GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
String licenseInfo = googleApiAvailability.getOpenSourceSoftwareLicenseInfo(activity);
if (licenseInfo != null) {
Context context = getDialogContext(activity);
RecyclerView recyclerView = createRecyclerView(context);
recyclerView.setAdapter(new LongMessageAdapter(context, licenseInfo));
builder.setView(recyclerView);
}
return builder.create();
}
private Context getDialogContext(Context context) {
TypedValue outValue = new TypedValue();
int resId = android.support.v7.appcompat.R.attr.dialogTheme;
context.getTheme().resolveAttribute(resId, outValue, true);
int themeId = outValue.resourceId;
return themeId == 0 ? context : new ContextThemeWrapper(context, themeId);
}
private RecyclerView createRecyclerView(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
@SuppressLint("InflateParams")
RecyclerView recyclerView = (RecyclerView) inflater.inflate(R.layout.recycler_dialog, null);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
return recyclerView;
}
private static final class LongMessageAdapter
extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context context;
private final String[] lines;
public LongMessageAdapter(Context context, String message) {
this.context = context;
this.lines = message.split("\\n");
}
@Override
public int getItemCount() {
return lines.length;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
TextView textView = new TextView(context);
textView.setTextAppearance(context, R.style.TextAppearance_AppCompat_Subhead);
return new RecyclerView.ViewHolder(textView) {
};
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((TextView) holder.itemView).setText(lines[position]);
}
}
}
recycler_dialog.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="?attr/dialogPreferredPadding"
android:paddingRight="?attr/dialogPreferredPadding"
android:paddingTop="@dimen/abc_dialog_padding_top_material"
android:scrollbars="vertical"/>
答案 1 :(得分:0)
您可以做的是初始化某种进度条或某些&#34;请等待&#34;对话框,然后在启动asynctask线程后立即检索doInBackground上的文本。
这样你就可以避免在UI线程上进行长时间调用而你的应用程序不会冻结。 然后使用该asynctask的onPostExecute删除&#34;请等待&#34;对话框(或您选择使用的任何内容)并显示文本。
另一个想法是只在滚动条中调用几行,并在用户向下滚动时加载更多行。
抱歉,如果只回答了一些想法,希望它可以为你启发一些东西。