Ошибка синтаксического анализа XML: несвязанный префикс в пользовательском LinearLayout - PullRequest
5 голосов
/ 05 января 2012

Я нашел этот пример Custom LinearLayout на stackoverflow , но он выдает ошибки, когда я пытаюсь его запустить, может кто-нибудь найти, что с ним не так?

Пользовательский LinearLayout:

package com.example.androidapp.widgets;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.LinearLayout;

public class ExpandablePanel extends LinearLayout {

    private final int mHandleId;
    private final int mContentId;

    private View mHandle;
    private View mContent;

    private boolean mExpanded = true;
    private int mCollapsedHeight = 0;
    private int mContentHeight = 0;

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

    public ExpandablePanel(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs,
            R.styleable.ExpandablePanel, 0, 0);

        // How high the content should be in "collapsed" state
        mCollapsedHeight = (int) a.getDimension(
            R.styleable.ExpandablePanel_collapsedHeight, 0.0f);

        int handleId = a.getResourceId(R.styleable.ExpandablePanel_handle, 0);
        if (handleId == 0) {
            throw new IllegalArgumentException(
                "The handle attribute is required and must refer "
                    + "to a valid child.");
        }

        int contentId = a.getResourceId(R.styleable.ExpandablePanel_content, 0);
        if (contentId == 0) {
            throw new IllegalArgumentException(
                "The content attribute is required and must refer "
                    + "to a valid child.");
        }

        mHandleId = handleId;
        mContentId = contentId;

        a.recycle();
    }

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

        mHandle = findViewById(mHandleId);
        if (mHandle == null) {
            throw new IllegalArgumentException(
                "The handle attribute is must refer to an"
                    + " existing child.");
        }

        mContent = findViewById(mContentId);
        if (mContent == null) {
            throw new IllegalArgumentException(
                "The content attribute is must refer to an"
                    + " existing child.");
        }

        mHandle.setOnClickListener(new PanelToggler());
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mContentHeight == 0) {
            // First, measure how high content wants to be
            mContent.measure(widthMeasureSpec, MeasureSpec.UNSPECIFIED);
            mContentHeight = mContent.getMeasuredHeight();
        }

        // Then let the usual thing happen
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    private class PanelToggler implements OnClickListener {
        @Override
        public void onClick(View v) {
            Animation a;
            if (mExpanded) {
                a = new ExpandAnimation(mContentHeight, mCollapsedHeight);
            } else {
                a = new ExpandAnimation(mCollapsedHeight, mContentHeight);
            }
            a.setDuration(500);
            mContent.startAnimation(a);
            mExpanded = !mExpanded;
        }
    }

    private class ExpandAnimation extends Animation {
        private final int mStartHeight;
        private final int mDeltaHeight;

        public ExpandAnimation(int startHeight, int endHeight) {
            mStartHeight = startHeight;
            mDeltaHeight = endHeight - startHeight;
        }

        @Override
        protected void applyTransformation(float interpolatedTime,
            Transformation t) {
            android.view.ViewGroup.LayoutParams lp = mContent.getLayoutParams();
            lp.height = (int) (mStartHeight + mDeltaHeight * interpolatedTime);
            mContent.setLayoutParams(lp);
        }

        @Override
        public boolean willChangeBounds() {
            // TODO Auto-generated method stub
            return true;
        }
    }
}

res> значения> attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="ExpandablePanel">
    <attr name="handle" format="reference" />
    <attr name="content" format="reference" />
    <attr name="collapsedHeight" format="dimension" />
  </declare-styleable>
</resources>

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:cl="http://schemas.android.com/apk/lib/com.example.androidapp.widgets"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

<com.example.androidapp.widgets.ExpandablePanel
    android:orientation="vertical"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    cl:handle="@+id/expand"
    cl:content="@+id/value"
    cl:collapsedHeight="50dip">
    <TextView
        android:id="@id/value"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:maxHeight="50dip"
        />
    <Button
        android:id="@id/expand"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="More" />
</com.example.androidapp.widgets.ExpandablePanel>


</LinearLayout>

Класс деятельности:

package com.example.androidapp.widgets;

import android.app.Activity;
import android.os.Bundle;

public class GoodPanelsActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

Ошибка LogCat:

ИСКЛЮЧИТЕЛЬНОЕ ИСКЛЮЧЕНИЕ: main java.lang.RuntimeException: невозможно запустить деятельность ComponentInfo {com.example.androidapp.widgets / com.example.androidapp.widgets.GoodPanelsActivity}: android.view.InflateException: строка двоичного файла XML №9: ошибка раздувает класс com.example.androidapp.widgets.ExpandablePanel

РЕДАКТИРОВАТЬ: больше от LogCat

java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.constructNative (собственный метод) в java.lang.reflect.Constructor.newInstance (Constructor.java:415) в android.view.LayoutInflater.createView (LayoutInflater.java:505) Причина by: java.lang.IllegalArgumentException: атрибут дескриптора требуется и должен относиться к действительному ребенку. в com.example.androidapp.widgets.ExpandablePanel. (ExpandablePanel.java:39)

Ответы [ 3 ]

6 голосов
/ 05 января 2012

Наконец я нашел проблему:

посмотрите на строку ниже в main.xml:

xmlns:cl="http://schemas.android.com/apk/lib/com.example.androidapp.widgets"

должно быть:

xmlns:cl="http://schemas.android.com/apk/res/com.example.androidapp.widgets"

Поскольку я не использую внешние библиотеки и ExpandablePanel существует под разрешением.

Приветствие.

0 голосов
/ 06 января 2012

Я также пробовал этот сценарий, так как я новичок в программировании на Android и искал несколько хороших примеров для изучения.

Мое приложение закрывается, когда я добавляю макет в основную.xml.

Когда я добавляю макет для ExpendablePanel, графический макет становится серым, и я не могу его редактировать:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:cl="http://schemas.android.com/apk/lib/com.martin.myapp.widgets"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

<com.martin.myapp.widgets.ExpandablePanel
    android:orientation="vertical"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    cl:handle="@+id/expand"
    cl:content="@+id/value"
    cl:collapsedHeight="50dip">
    <TextView
        android:id="@id/value"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:maxHeight="50dip"
        />
    <Button
        android:id="@id/expand"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="More" />
</com.martin.myapp.widgets.ExpandablePanel>

Так что это по сути пустое приложение безwidget.

Я сделал ExpandablePanel.java и скопировал скрипт, который расширяет LinearLayout, не дает мне ошибок.Мой файл attrs.xml также не содержит ошибок.

Eclipse не выдает никаких ошибок при запуске.Он запускается и отправляет его на мой телефон в порядке.Вот где сила закрывается.Когда я удаляю макет ExpandablePanel в main.xml, он запускается и становится пустым приложением.

Я действительно не могу понять это.

0 голосов
/ 05 января 2012

Вам необходимо добавить проект, содержащий этот класс com.example.androidapp.widgets.ExpandablePanel, в ваш проект buildpath.Если это не проект с открытым исходным кодом или источник недоступен, вы не сможете это сделать.

Если у вас есть этот проект, и это LibraryProject, вам следует щелкнуть правой кнопкой мыши на вашем Project->Properties->Android и в разделе Library добавьте этот проект.

Если это обычный Project, просто перейдите на Properties->Java Build Path->Projects и оттуда добавьте этот проект.

...