Android:在Fragment中扩展自定义视图

时间:2016-08-06 22:27:42

标签: java android xml android-fragments android-canvas

我有一个应用程序,它使用片段视图作为其布局的一部分。在这个片段中,我想实例化一个Paint Canvas,我可以在其中进行自定义绘图。

问题是,当我用错误Perl

来充气片段时,我的应用程序崩溃了

我不确定是什么导致我的Paint类不能正常充气。我知道有关如何在片段中使用findViewById的特殊规则,但我认为我坚持它们,因为我在片段的视图本身上调用了findViewByid(在我的代码中称为“v”)。

如何解决此问题?

FragmentNeckDisplayMenu.java(片段类)

android.view.InflateException: Binary XML file line #15: Binary XML file line #15: Error inflating class com.example.xxxxx.NeckCanvasOverlay

NeckCanvasOverlay.java(Paint Class)

public class FragmentNeckDisplayMenu extends Fragment {
    private static View v;
    private NeckCanvasOverlay neckHUD;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        v = inflater.inflate(R.layout.menu_fragment_neck_display,container,false);      //ERROR HERE
        NeckCanvasOverlay neckHUD = (NeckCanvasOverlay) v.findViewById(R.id.neckHUD);   //paint test
        ...
        return v;
    }
}

menu_fragment_neck_display.xml(片段的布局)

class NeckCanvasOverlay extends View {
    private Paint mPainter;

    public NeckCanvasOverlay(Context context) {
        super(context);
        initView();
    }

    private void initView(){    //Initializes canvas & paint objects here to save performance
        mPainter = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPainter.setColor(Color.BLUE);
        mPainter.setAlpha(128);
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(180, 900, 200, mPainter);
    }
}

完整堆栈跟踪(编辑:包含完整跟踪)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/canvas"
    android:background="@drawable/image">

    <LinearLayout
        android:layout_width="148dp"
        android:layout_height="0dp"
        android:layout_gravity="center"
        android:layout_weight="4">
        !--Custom view for Canvas here -->
        <com.example.xxxxx.NeckCanvasOverlay
            android:id="@+id/neckHUD"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:background="@drawable/neck_for_menu"/>
    </LinearLayout>

    <Button
        android:id="@+id/menuIcon"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginTop="64dp"
        android:text="Menu"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_gravity="bottom"
        android:layout_weight="0.5"/>
</LinearLayout>

2 个答案:

答案 0 :(得分:4)

当前问题是ClassNotFoundException。在布局中处理自定义View时,常见的原因是布局XML中的类名不正确,这似乎是此处的问题。确保XML标记具有自定义View类的正确的完全限定类名,该类将是文件顶部的类package,前缀为类名。

此外,从您的布局中膨胀的View将使用带有ContextAttributeSet的双参数构造函数进行实例化。您的类定义至少需要具有允许通胀的构造函数,否则您将获得NoSuchMethodException。此外,如果您只是扩展View,那么如果您链接构造函数,它会使事情变得更简单一些。例如:

public NeckCanvasOverlay(Context context) {
    this(context, null);
}

public NeckCanvasOverlay(Context context, AttributeSet attrs) {
    super(context, attrs);
    initView();
}

答案 1 :(得分:0)

为自定义View包含所有三个构造函数更安全。例如,为NeckCanvasOverlay包含以下构造函数。

public NeckCanvasOverlay(Context context) {
        super(context);
        initView();
    }

    public NeckCanvasOverlay(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public NeckCanvasOverlay(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initView();
    }

我希望这会有所帮助。试一试,如果你收到同样的错误,请告诉我。

相关问题