java - 将 MPAndroidChart 图表保存到图像而不在活动上显示
问题描述
我想生成一个 PDF,但首先我需要从LineChart(MPAndroidChart 库)创建一个图像,而不在活动中显示它。
我已经按照本教程http://android-crap.blogspot.com/2013/02/create-bitmap-from-layoutview.html进行了操作,并且根据自己的要求修改了代码:
private void createLineChart(double frequency) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout view = new RelativeLayout(activity);
inflater.inflate(R.layout.line_chart_layout, view, true);
LineChart lc = view.findViewById(R.id.lncMain);
lc.setData(createLineData(frequency));
lc.invalidate();
view.setLayoutParams(new LinearLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
view.draw(c);
String filename = "graph.png";
File sd = Environment.getExternalStorageDirectory();
File dest = new File(sd, filename);
try {
FileOutputStream out = new FileOutputStream(dest);
b.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Log.i(TAG, filename);
}
该activity
变量是 的一个实例AppCompatActivity
。的R.layout.line_chart_layout
内容:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layParent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<com.github.mikephil.charting.charts.LineChart
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/lncMain"
android:orientation="horizontal"
>
</com.github.mikephil.charting.charts.LineChart>
</RelativeLayout>
应用程序执行后,我会得到一个名为 的图像文件graph.png
,但其内容并不反映期望图:
我为 , 尝试了不同的值view.setLayoutParams
,view.layout
但它不起作用......请提出一些建议!
解决方案
我的猜测是 graph.png 看起来很混乱,因为LineChart
它从未真正添加到Activity
's 的布局中,因此它的“实际大小”计算不正确。我知道您不想向用户显示图表,但可以通过设置View
不可见来实现这一点。
所以这是我的版本:
public class MainActivity extends AppCompatActivity {
private LineChart lc;
private RelativeLayout view;
private static final String TAG = "LCTP Main";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onResume() {
super.onResume();
if(Build.VERSION.SDK_INT > 22 && (checkSelfPermission(WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED)) {
requestPermissions(new String[]{READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE}, 13);
}
else {
createLineChart(440.0);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == 13){
boolean ok = true;
int length = permissions.length;
for (int i = 0; i < length; i++) {
String permission = permissions[i];
if(grantResults[i] != PERMISSION_GRANTED){
Log.d(TAG, "onRequestPermissionsResult: missing permission " + permission);
ok = false;
}
}
if(ok){
createLineChart(220);
}
}
}
private void createLineChart(double frequency) {
if(lc == null){
view = findViewById(R.id.layParent);
lc = findViewById(R.id.lncMain);
}
lc.setData(createLineData(frequency));
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
Bitmap b = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
view.draw(c);
String filename = "graph.png";
File sd = Environment.getExternalStorageDirectory();
File dest = new File(sd, filename);
try {
FileOutputStream out = new FileOutputStream(dest);
b.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Log.i(TAG, filename);
}
});
lc.invalidate();
}
private LineData createLineData(double frequency) {
List<Entry> yVals = new ArrayList<>();
for(int i = 0; i < frequency; i = i + 10){
yVals.add(new Entry(i, (float)Math.sin(i*i)));
}
ILineDataSet lineDataSet = new LineDataSet(yVals, "LabelString");
LineData lineData = new LineData(lineDataSet);
return lineData;
}
}
活动主.xml:
<LinearLayout
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"
android:padding="24dp"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Hello World!"/>
<include
layout="@layout/line_chart_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"/>
</LinearLayout>
生成的png:
推荐阅读
- javascript - 仅使用 EJS 和 res.render 加载 JS 文件一次
- php - 需要为具有特定 php 模板的页面分配自定义分类 - Wordpress
- vba - 在 powerpoint 退出演示文稿后让代码工作
- amazon-web-services - Route53 不解析 DNS 配置
- xamarin.forms - Xamarin.forms 未在添加新项目中列出
- javascript - Javascript全局函数替换事件
- php - 在 laravel 问题中更改索引刀片
- php - 如何从 laravel 中的某个路由页面检索图像或文件?
- python - 在 python 中使用 cv2 创建图像数据集时出错
- vba - 更改 CATIA 中主动选择项目的名称