如何将自定义视图添加到布局?

Posted

技术标签:

【中文标题】如何将自定义视图添加到布局?【英文标题】:How add custom view to layout? 【发布时间】:2011-07-12 11:03:05 【问题描述】:

我有一个自定义视图

  public GraphView(Context context, float[] values, String title, String[]horlabels,  String[] verlabels, boolean type, int color) 
    super(context);
    if (values == null)
        this.values = new float[0];
    else
        this.values = values;
    if (title == null)
        title = "";
    else
        this.title = title;
    if (horlabels == null)
        this.horlabels = new String[0];
    else
        this.horlabels = horlabels;
    if (verlabels == null)
        this.verlabels = new String[0];
    else
        this.verlabels = verlabels;
    this.type = type;
    paint = new Paint();
    this.color = color;


@Override
protected void onDraw(Canvas canvas) 
    float border = 20;
    float horstart = border * 2;
    float height = getHeight();
    float width = getWidth() - 1;
    float max = getMax();
    float min = getMin();
    float diff = max - min;
    float graphheight = height - (2 * border);
    float graphwidth = width - (2 * border);

    paint.setTextAlign(Align.LEFT);
    int vers = verlabels.length - 1;
    for (int i = 0; i < verlabels.length; i++) 
        paint.setColor(Color.DKGRAY);
        float y = ((graphheight / vers) * i) + border;
        canvas.drawLine(horstart, y, width, y, paint);
        paint.setColor(Color.BLACK);
        canvas.drawText(verlabels[i], 0, y, paint);
    
    int hors = horlabels.length - 1;
    for (int i = 0; i < horlabels.length; i++) 
        paint.setColor(Color.DKGRAY);
        float x = ((graphwidth / hors) * i) + horstart;
        canvas.drawLine(x, height - border, x, border, paint);
        paint.setTextAlign(Align.CENTER);
        if (i==horlabels.length-1)
            paint.setTextAlign(Align.RIGHT);
        if (i==0)
                paint.setTextAlign(Align.LEFT);
        paint.setColor(Color.BLACK);
        canvas.drawText(horlabels[i], x, height - 4, paint);
    

    paint.setTextAlign(Align.CENTER);
    canvas.drawText(title, (graphwidth / 2) + horstart, border - 4, paint);

    if (max != min) 
        paint.setColor(color);
        if (type == BAR) 
            float datalength = values.length;
            float colwidth = (width - (2 * border)) / datalength;
            for (int i = 0; i < values.length; i++) 
                float val = values[i] - min;
                float rat = val / diff;
                float h = graphheight * rat;
                canvas.drawRect((i * colwidth) + horstart, (border - h) + graphheight, ((i * colwidth) + horstart) + (colwidth - 1), height - (border - 1), paint);
            
         else 
            float datalength = values.length;
            float colwidth = (width - (2 * border)) / datalength;
            float halfcol = colwidth / 2;
            float lasth = 0;
            for (int i = 0; i < values.length; i++) 
                float val = values[i] - min;
                float rat = val / diff;
                float h = graphheight * rat;
                if (i > 0)
                    canvas.drawLine(((i - 1) * colwidth) + (horstart + 1) + halfcol, (border - lasth) + graphheight, (i * colwidth) + (horstart + 1) + halfcol, (border - h) + graphheight, paint);
                lasth = h;
            
        
    


private float getMax() 
    float largest = Integer.MIN_VALUE;
    for (int i = 0; i < values.length; i++)
        if (values[i] > largest)
            largest = values[i];
    return largest;


private float getMin() 
    float smallest = Integer.MAX_VALUE;
    for (int i = 0; i < values.length; i++)
        if (values[i] < smallest)
            smallest = values[i];
    return smallest;

当我打电话时 设置内容视图(图形视图); 效果很好,但是当我打电话时

            diagramRelativeLayout = (RelativeLayout)switcher.getChildAt(i).findViewById(R.id.diagramRelativeLayout);
            diagramRelativeLayout.addView(graphView);

这是行不通的。

 Error:07-12 11:07:38.933: ERROR/androidRuntime(30488): java.lang.RuntimeException:  Unable to resume activity com.meters.src/com.meters.src.Main_Activity:  java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

RelativeLayout 包含在ViewFlipper 中。如何将我的视图添加到此布局中?

【问题讨论】:

【参考方案1】:

您不必使用代码添加视图,您可以像任何 android 视图一样在 xml 中添加视图: 在您的情况下,只需在您不想查看的 xml 中添加以下代码

<com.your.package.GraphView android:id="@+id/myGraphView" />

然后在您的活动中,您可以使用

检索它
GraphView myGV = (GraphView) findViewById(R.id.myGraphView);

【讨论】:

07-12 15:15:59.133:错误/AndroidRuntime(31020):java.lang.RuntimeException:无法恢复活动 com.meters.src/com.meters.src.Main_Activity: android.view.InflateException: Binary XML file line #136: Error inflating class com.meters.src.GraphView【参考方案2】:

视图只能有一个父视图。您正在添加的视图(我猜想重新使用,即 graphView)已经是另一个视图层次结构的一部分。如果您真的想重用它(我建议您可能不要),那么您必须将它与现有视图层次结构中的父级分离。

【讨论】:

检查您已经将此 graphView 添加到了 diagramRelativeLayout.addView(graphView); 我只在oncreate中初始化()graphView = new GraphView(context, values, "Weekly Usage (kW)",horlabels, verlabels, GraphView.BAR, Color.RED); 这个方法,返回ViewFlipper的子节点。【参考方案3】:

添加如下代码行,

diagramRelativeLayout = (RelativeLayout)switcher.getChildAt(i).findViewById(R.id.diagramRelativeLayout);

diagramRelativeLayout.removeAllViewsInLayout();  // <-- Add this and try

diagramRelativeLayout.addView(graphView);

【讨论】:

【参考方案4】:

我做到了,我只是用一个布局制作了xml,并在diagramRelativeLayout中添加了对它的引用:

我的 xml:

  <RelativeLayout
  android:id = "@+id/diagramRelativeLayout"
  android:background="@layout/button_style"
  android:layout_
  android:layout_height = "fill_parent"
  android:layout_marginTop = "10sp"
  android:layout_marginLeft = "5sp"
  android:layout_marginRight = "5sp"
  android:layout_marginBottom = "10sp"
  android:gravity="center"> 
    <include android:id="@+id/graph" layout="@layout/graph"/>  
  </RelativeLayout>

我的 java:

graphLayout = (RelativeLayout)switcher.getChildAt(i).findViewById(R.id.graph);
graphLayout.addView(graphView);

【讨论】:

以上是关于如何将自定义视图添加到布局?的主要内容,如果未能解决你的问题,请参考以下文章

将自定义视图动态添加到 iOS 中的每个视图控制器

Android:创建自定义视图并将其动态添加到布局中

如何将自定义视图+控制器添加到模型?

如何以编程方式将自定义 uiview 添加到视图控制器 SWIFT

如何将自定义视图添加到 JSQMessagesViewController 单元格,以便它包含一个带有一些按钮和文本视图的视图?

将自定义视图附加到 Android 键盘的顶部