Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/190.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用<;包括>;在自定义复合视图中,onFinishInflate()中会导致NullPointerException_Java_Android_Android Layout_Android Custom View_Android Xml - Fatal编程技术网

Java 使用<;包括>;在自定义复合视图中,onFinishInflate()中会导致NullPointerException

Java 使用<;包括>;在自定义复合视图中,onFinishInflate()中会导致NullPointerException,java,android,android-layout,android-custom-view,android-xml,Java,Android,Android Layout,Android Custom View,Android Xml,我正在尝试实现一个简单的自定义拨号板视图。在我尝试使用为我的按钮包含一个“模板”,而不是在XML文件中显式定义每个按钮之前,一切都很顺利。因为我将有12个几乎相同的按钮,所以我认为这样做只会使我的XML更简洁 问题是,在自定义视图中的onfinishflate()中,当我调用findViewById(R.id.dialpad\u view\u btn1)时,它返回null。当然,我正在将iddialpad\u view\u btn1分配给我的一个。如果我只是显式地定义按钮,而不是从“模板”中包含

我正在尝试实现一个简单的自定义拨号板视图。在我尝试使用
为我的按钮包含一个“模板”,而不是在XML文件中显式定义每个按钮之前,一切都很顺利。因为我将有12个几乎相同的按钮,所以我认为这样做只会使我的XML更简洁

问题是,在自定义视图中的
onfinishflate()
中,当我调用
findViewById(R.id.dialpad\u view\u btn1)
时,它返回null。当然,我正在将id
dialpad\u view\u btn1
分配给我的一个
。如果我只是显式地定义按钮,而不是从“模板”中包含按钮,那么它就可以正常工作。是否有解决方法,或者我应该接受
findViewById()
不能很好地结合在一起

DialPadView.java

public class DialPadView extends android.support.v7.widget.GridLayout {


    public DialPadView(Context context) {
        super(context);
        initializeViews(context);
    }

    public DialPadView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initializeViews(context);
    }

    public DialPadView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initializeViews(context);
    }

    private void initializeViews(Context context) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.dialpad_view, this);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        // This call to findViewById() results in a NullPointerException
        ((ImageButton) findViewById(R.id.dialpad_view_btn1)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // I'm just a dummy
            }
        });
    }

}
dialpad\u view.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.me.myproject.DialPadView"
    xmlns:grid="http://schemas.android.com/apk/res-auto"
    android:id="@+id/dialpad_grid_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
    grid:alignmentMode="alignMargins"
    grid:columnCount="3"
    grid:rowCount="4">

    <include
        android:id="@+id/dialpad_view_btn1"
        layout="@layout/dialpad_button" />

    <include
        android:id="@+id/dialpad_view_btn2"
        layout="@layout/dialpad_button" />


</android.support.v7.widget.GridLayout>
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:grid="http://schemas.android.com/apk/res-auto">

    <Button
        android:layout_width="0dp"
        android:layout_height="0dp"
        grid:layout_columnWeight="1"
        grid:layout_rowWeight="1"
        grid:layout_gravity="fill"
        android:layout_margin="5dp"
        android:scaleType="centerInside"
        android:text="Test" />

</merge>

拨号盘按钮.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.me.myproject.DialPadView"
    xmlns:grid="http://schemas.android.com/apk/res-auto"
    android:id="@+id/dialpad_grid_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
    grid:alignmentMode="alignMargins"
    grid:columnCount="3"
    grid:rowCount="4">

    <include
        android:id="@+id/dialpad_view_btn1"
        layout="@layout/dialpad_button" />

    <include
        android:id="@+id/dialpad_view_btn2"
        layout="@layout/dialpad_button" />


</android.support.v7.widget.GridLayout>
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:grid="http://schemas.android.com/apk/res-auto">

    <Button
        android:layout_width="0dp"
        android:layout_height="0dp"
        grid:layout_columnWeight="1"
        grid:layout_rowWeight="1"
        grid:layout_gravity="fill"
        android:layout_margin="5dp"
        android:scaleType="centerInside"
        android:text="Test" />

</merge>

ID有问题: 您遇到的问题是由混合使用
标记引起的。 请注意,
有不同的用途,在这种情况下不应使用它,因此请仅使用
,并将
作为拨号盘按钮.xml文件的根目录。然后所有ID都应该正确分配

<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:grid="http://schemas.android.com/apk/res-auto">
    android:layout_width="0dp"
    android:layout_height="0dp"
    grid:layout_columnWeight="1"
    grid:layout_rowWeight="1"
    grid:layout_gravity="fill"
    android:layout_margin="5dp"
    android:scaleType="centerInside"
    android:text="Test" />

但是
已经是
android.support.v7.widget.GridLayout
的一个实例,所以基本上你最终拥有
GridLayout
内部的
GridLayout
。除了没有达到最佳效果之外,它还可能导致布局的外观与您想象的外观和行为不同。

尝试从
dialpad_button.xml中删除
标记,使
成为此文件的根目录。在xml中使用,而不是@pskink这是
DialPadView的xml,不适用于使用自定义视图的布局。我不明白,那你在哪里创建DialPadView呢?@pskink在我的
活动的布局中
当然,我不认为我也需要包括它,因为它与问题无关?你认为我应该包括
AndroidManifest.xml
build.gradle
,等等?这就是我问题的答案。然而,事实证明这个问题是错误的。为了简化代码,我改变了使用
ImageButton
而不是
Button
。使用透明背景的
ImageButton
s时,如果不使用
作为根目录,则按钮似乎不会显示。在进一步调查中,按钮确实会显示,但它们不会缩放到
网格布局
,图像也不会显示。我将开始一个新问题,因为现在问题不再是
NullPointerException
,而是布局问题。谢谢。我已经更新了我的答案,把重点放在pskink提到的事情上。尽管这不是问题中提到的
NullPointerException
的原因,但这仍然是一件错误的事情,您应该调查并修复它。我尝试使用
作为我的DialPadView的根,但这破坏了
GridLayout
的功能-它的所有子项都在同一行上,不在行和列中。我是否应该从
GridLayout
以外的东西继承视图类,以避免有两个嵌套的GridLayout?当根元素和基类都是
GridLayout
…两种解决方案:1。如果要在DialPadView文件中对子项进行充气,则需要使用
标记而不是
,但这样会丢失所有属性(合并无法传递属性),因此需要在活动XML文件中应用它们。2.只需将
替换为XML文件中的
DialPadView
类,并将其用作活动的一部分。然后不要在自定义类中膨胀子视图。它们已经在那里膨胀了。您可以创建一个新问题,因为这里的字符限制太小:(我不能在DialPadView类中扩展
LinearLayout
,并将
GridLayout
保留为XML根目录吗?