我正在使用 achart 引擎成功显示饼图。我想根据屏幕大小自定义标签文本大小。提前致谢。
7 回答
这个问题归结为解决方案。achartengine 在设计时似乎考虑了原始像素,而显示质量和像素密度在过去几年中急剧增加。来自 achartengine 样本的标签在我的 HTC One 上很小!
Android 引入了与比例无关的像素。将它们与 achartengine 一起使用的关键是TypedValue
类。这是我所做的:
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
float val = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 18, metrics);
我从上面链接中的“中等大小的文本”中得到了 18 个。
然后,您可以val
在任何您想使用中等大小文本的地方使用。例如:
renderer.setLabelsTextSize(val);
这是我所做的总结版本:
public static final int TEXT_SIZE_XHDPI = 24;
public static final int TEXT_SIZE_HDPI = 20;
public static final int TEXT_SIZE_MDPI = 18;
public static final int TEXT_SIZE_LDPI = 13;
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
switch (getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_XHIGH:
renderer.setMargins(new int[] { 40, 90, 25, 10 });
renderer.setAxisTitleTextSize(Constants.TEXT_SIZE_XHDPI);
renderer.setChartTitleTextSize(Constants.TEXT_SIZE_XHDPI);
renderer.setLabelsTextSize(Constants.TEXT_SIZE_XHDPI);
renderer.setLegendTextSize(Constants.TEXT_SIZE_XHDPI);
break;
case DisplayMetrics.DENSITY_HIGH:
renderer.setMargins(new int[] { 30, 50, 20, 10 });
renderer.setAxisTitleTextSize(Constants.TEXT_SIZE_HDPI);
renderer.setChartTitleTextSize(Constants.TEXT_SIZE_HDPI);
renderer.setLabelsTextSize(Constants.TEXT_SIZE_HDPI);
renderer.setLegendTextSize(Constants.TEXT_SIZE_HDPI);
break;
default:
renderer.setMargins(new int[] { 30, 50, 20, 10 });
renderer.setAxisTitleTextSize(Constants.TEXT_SIZE_LDPI);
renderer.setChartTitleTextSize(Constants.TEXT_SIZE_LDPI);
renderer.setLabelsTextSize(Constants.TEXT_SIZE_LDPI);
renderer.setLegendTextSize(Constants.TEXT_SIZE_LDPI);
break;
}
所以我基本上根据设备的屏幕密度自定义了图表的边距和文本大小。注意:我暂时排除了中等密度的情况。
我编写了两个名为 _dp 和 _sp 的方法来转换为 dp 和 sp 值。
private DisplayMetrics displayMetrics;
private boolean isPortrait;
int _dp(float pixels) {
return (int)(pixels * displayMetrics.density);
}
float _sp(float pixels) {
return (pixels * displayMetrics.scaledDensity);
}
在您的 onCreate 中,您需要设置 displayMetrics 值:
displayMetrics = (this.getResources()).getDisplayMetrics();
然后您只需使用 _sp 和 _dp 即可获得 sp/dp 值。例如将字体设置为 18
renderer.setAxisTitleTextSize(_sp(18));
并使用 dp 值设置边距:
renderer.setMargins(new int[] {_dp(25), _dp(30), _dp(35), _dp(20)});
注意:我对此代码进行了一项更改。这些函数有可能得到 0 值——如果你除以返回值,这是一个真正的问题。如果返回值 < 1,我添加了一个返回 1 的测试。即:return ((rv < 1) ? 1 : v);
您可以通过这种方式设置标签文本大小:
renderer.setLabelsTextSize(size);
您必须找到最佳逻辑来找到屏幕尺寸和标签尺寸之间的最佳比例。
最佳做法是将虚拟 TextView 放入布局中以获取 textSize:
<TextView
android:id="@+id/dummyTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:text="TextView" />
例如在您的代码中:
TextView testTextView = (TextView) rootView.findViewById(R.id.dummyTextView);
float textSize = testTextView.getTextSize();
renderer.setLabelsTextSize(textSize);
renderer.setLegendTextSize(textSize);
我认为最好的方法是dimens.xml
在 dp 和 sp 中定义文件的大小,如下所示:
<dimen name="graph_chart_text_size">16sp</dimen>
<dimen name="graph_axis_title_text_size">14sp</dimen>
<dimen name="graph_labels_text_size">12sp</dimen>
<dimen name="graph_labels_padding">5dp</dimen>
<dimen name="graph_legend_text_size">14sp</dimen>
<dimen name="graph_legend_height">40dp</dimen>
<dimen name="graph_point">3dp</dimen>
<dimen name="graph_line">3dp</dimen>
<dimen name="graph_margin_top">10dp</dimen>
<dimen name="graph_margin_left">40dp</dimen>
<dimen name="graph_margin_right">10dp</dimen>
<dimen name="graph_margin_bottom">20dp</dimen>
然后在配置渲染器时使用getDimension和getDimensionPixelOffset转换为像素,如:
renderer.setChartTitleTextSize(context.getResources().getDimension(R.dimen.graph_chart_text_size));
renderer.setAxisTitleTextSize(context.getResources().getDimension(R.dimen.graph_axis_title_text_size));
renderer.setLabelsTextSize(context.getResources().getDimension(R.dimen.graph_labels_text_size));
renderer.setLegendTextSize(context.getResources().getDimension(R.dimen.graph_legend_text_size));
renderer.setLegendHeight(context.getResources().getDimensionPixelOffset(R.dimen.graph_legend_height));
renderer.setMargins(new int[]{
context.getResources().getDimensionPixelOffset(R.dimen.graph_margin_top),
context.getResources().getDimensionPixelOffset(R.dimen.graph_margin_left_mood),
context.getResources().getDimensionPixelOffset(R.dimen.graph_margin_bottom),
context.getResources().getDimensionPixelOffset(R.dimen.graph_margin_right)});
}
我在 800x480 到 1920x1080 的手机上进行了测试,设计非常一致。
你可以试试这个:
renderer.setLegendTextSize(textSize);