【问题标题】:Passing data to custom view in Android将数据传递给Android中的自定义视图
【发布时间】:2016-11-07 18:50:20
【问题描述】:

我对 Android 还很陌生,正在尝试创建一个自定义视图来显示饼图。我对 Java 没问题,之前用 iOS/Swift 写过饼图代码。

我的问题是数据似乎没有像我预期的那样被传递,或者可能是在从超类以某种方式设置数据之前调用了 onDraw 函数。

我想知道传递要在 onDraw 函数中使用的数据的最佳方法。到目前为止,在Android Custom View Constructor 等帖子的帮助下,我得到了以下代码:

public PieChart(Context _context) {
    this(_context, null);
}
public PieChart(Context _context, AttributeSet _attrs) {
    this(_context, _attrs, null);
}
public PieChart(Context _context, AttributeSet _attrs, ArrayList<ChartData> _data) {
    super(_context, _attrs);
    if(this.isInEditMode()) {
        data = new ArrayList<ChartData>();
        data.add(new ChartData("Column A", 50));
        data.add(new ChartData("Column B", 75));
        data.add(new ChartData("Column C", 60));
    } else {
        data = _data;
    }
    context = _context;
    paint = new Paint();
    paint.setAntiAlias(true);
    paint.setStyle(Paint.Style.FILL);
    pieRectangle = new RectF(0,0,0,0);
    ...
}

从我的活动中调用如下:

// create the chart
PieChart pieChart = new PieChart(this, null, categoriesChartData);
// add the chart to the linearLayout
linearLayout.addView(pieChart);

我的 PieChart.onDraw 是这样开始的:

protected void onDraw(Canvas canvasChart) {
    Log.d(TAG, "Size of data = " + data.size()); // crashes here
    ...
}

请注意,在界面设计器中,饼图看起来很棒,所以我知道 onDraw 方法有效,只是在运行应用程序时数据没有出现。

我没有添加额外的函数和调用,因为我在 Android 方面没有太多经验,我想问问社区有什么问题以及最好的方法是什么。

非常感谢!

【问题讨论】:

  • 你在为视图扩展什么?为什么是 if(this.isInEditMode()) ?
  • 您不应添加新的自定义构造函数。您应该添加一个 setter。
  • 如果有错误请发布logcat。
  • @OgnianGloushkov 因为这样我就可以在界面设计器中看到饼图

标签: java android


【解决方案1】:

由于您提到了界面设计器,我假设您也将视图添加到 XML 布局中。在这种情况下,Android View 框架将使用这个构造函数(按照惯例):

public PieChart(Context _context, AttributeSet _attrs)

这就是你的datanull 的原因。对于视图,您必须为数据创建一个 setter 方法,而不是将其作为构造函数参数传递。

此外,如果您已经在 XML 布局中声明了视图,则无需手动创建它 - 这只会在布局中添加另一个视图。

【讨论】:

    【解决方案2】:

    由于使用构造函数不是理想的;您可以构建一个接受数据数组的方法,在您的情况下是ArrayList&lt;CharData&gt;List&lt;CharData&gt;

    public PieChart(Context _context) {
        this(_context, null);
    }
    public PieChart(Context _context, AttributeSet _attrs) {
        super(_context, _attrs);
        if(this.isInEditMode()) {
            data = new ArrayList<ChartData>();
            data.add(new ChartData("Column A", 50));
            data.add(new ChartData("Column B", 75));
            data.add(new ChartData("Column C", 60));
        }
    
        context = _context;
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);
        pieRectangle = new RectF(0,0,0,0);
        ...
    }
    
    protected void onDraw(Canvas canvasChart) {
        if(data != null){
           Log.d(TAG, "Size of data = " + data.size());
           // more codes here
        }
    }
    
    public void setValues(List<CharData> d){
       data = d;
    }
    

    最终的用例如下:

    PieChart pieChart = new PieChart(this, null);
    linearLayout.setValues(categoriesChartData);
    linearLayout.addView(pieChart);
    

    【讨论】:

    • 对不起,它更进一步 - 我已经更新了我的代码以反映这一点。据我所知,这不是问题。
    【解决方案3】:

    我认为data 为空,因为this.isInEditMode() 返回 false。你应该先检查它。

    【讨论】:

      猜你喜欢
      • 2015-05-12
      • 1970-01-01
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多