2

リストの各行をカスタマイズするために使用される別の xml ファイルからボタンにアクセスしようとしています。しかし、onClickリスナーの設定中にnullpointer例外が発生しているため、どうすればこれを行うことができますか. 私のコードを以下に示します。

main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
        >
    <ListView android:id="@+id/List"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"/>
</LinearLayout>

行.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/list_item">

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/list_item_text_view"
android:textSize="20sp"
android:padding="10dp"
android:layout_weight="1"
android:layout_marginLeft="35dp" />

<Button
    android:id="@+id/b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>

この私の活動クラス

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

Button b1 = (Button)findViewById(R.id.b1);
b1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

            }
        });

基本的に、アクティビティ ビューが main.xml に設定されているときに、onclicklistener を row.xml の b1 に設定する方法

4

2 に答える 2

3

LayoutInflater を使用します。

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

        LayoutInflater inflater = this.getLayoutInflater();
        LinearLayout v = (LinearLayout)inflater.inflate(R.layout.hello, null);
        Button bt1 = (Button)v.findViewById(R.id.btLog);
        bt1.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub

            }
        });
    }
}

更新*拡張可能なレイアウト*

public class ExpandablePanel extends LinearLayout {

    private final int mHandleId;
    private final int mContentId;

    private View mHandle;
    private View mContent;

    private boolean mExpanded = false;
    private int mCollapsedHeight = 0;
    private int mContentHeight = 0;
    private int mAnimationDuration = 0;

    private OnExpandListener mListener;

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

    public ExpandablePanel(Context context, AttributeSet attrs) {
        super(context, attrs);
        mListener = new DefaultOnExpandListener();



        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);

        // How long the animation should take
        mAnimationDuration = a.getInteger(R.styleable.ExpandablePanel_animationDuration, 500);

        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();
    }

    public void setOnExpandListener(OnExpandListener listener) {
        mListener = listener; 
    }

    public void setCollapsedHeight( int collapsedHeight ) { mCollapsedHeight = collapsedHeight; android.view.ViewGroup.LayoutParams lp = mContent.getLayoutParams(); lp.height = mCollapsedHeight; mContent.setLayoutParams( lp ); }

    public void setAnimationDuration(int animationDuration) {
        mAnimationDuration = animationDuration;
    }

    @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 must refer to an"
                    + " existing child.");
        }

        android.view.ViewGroup.LayoutParams lp = mContent.getLayoutParams();
        lp.height = mCollapsedHeight;
        mContent.setLayoutParams(lp);

        mHandle.setOnClickListener(new PanelToggler());
    }

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

        if (mContentHeight < mCollapsedHeight) {
            mHandle.setVisibility(View.GONE);
        } else {
            mHandle.setVisibility(View.VISIBLE);
        }

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

    private class PanelToggler implements OnClickListener {
        public void onClick(View v) {
            Animation a;
            if (mExpanded) {
                a = new ExpandAnimation(mContentHeight, mCollapsedHeight);
                mListener.onCollapse(mHandle, mContent);
            } else {
                a = new ExpandAnimation(mCollapsedHeight, mContentHeight);
                mListener.onExpand(mHandle, mContent);
            }
            a.setDuration(mAnimationDuration);
            if(mContent.getLayoutParams().height == 0) //Need to do this or else the animation will not play if the height is 0
            {
                android.view.ViewGroup.LayoutParams lp = mContent.getLayoutParams();
                lp.height = 1;
                mContent.setLayoutParams(lp);
                mContent.requestLayout();
            }
            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() {
            return true;
        }
    }

    public interface OnExpandListener {
        public void onExpand(View handle, View content); 
        public void onCollapse(View handle, View content);
    }

    private class DefaultOnExpandListener implements OnExpandListener {
        public void onCollapse(View handle, View content) {}
        public void onExpand(View handle, View content) {}
    }
}

レイアウト: これを一番上に置きます: xmlns:cl="http://schemas.android.com/res/com.example.androidapp.widgets" Eclipse は、ExpandablePanel で例外をスローするため、常にこのレイアウトでエラーを示します。クラスなので、これらの行を非表示にして、展開可能なレイアウトがどのように表示されるかを確認し、ボタンとテキストの子を設定できます。

<com.example.androidapp.widgets.ExpandablePanel
        android:id="@+id/theId"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:collapsedHeight="80dp"
        app:content="@+id/value"
        app:handle="@+id/expand"
        cl:collapsedHeight="50dip"
        cl:content="@+id/value"
        cl:handle="@+id/expand" >

        <TextView
            android:id="@id/value"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="hejahdkashfa afsjkhas lf ksajfh as fkjsah asf kfsahkjfas  klfajsh flkas  klfajsh lasfkl aklfsjh klsa ffhaskljfha dfasfa s safjsfkhasjkf fjakshfjkasf  jksfhjkasf sjakfhas kjfa sjkfhakjsfh asjsfhkjashf askjsf sakjfh as fadsfasf af asf asf" />

        <Button
            android:id="@id/expand"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical|center_horizontal"
            android:text="More" />

    </com.example.androidapp.widgets.ExpandablePanel>

エキスパンド パネルの設定方法:

// Set expandable panel listener
        ExpandablePanel panel = (ExpandablePanel)findViewById(R.id.theId);
        panel.setCollapsedHeight(50);
        panel.setContentDescription(descricao);
        panel.setOnExpandListener(new ExpandablePanel.OnExpandListener() {
            public void onCollapse(View handle, View content) {
                Button btn = (Button)handle;
                btn.setText("More");
            }
            public void onExpand(View handle, View content) {
                Button btn = (Button)handle;
                btn.setText("Less");
            }
        });
于 2013-01-25T14:13:02.597 に答える
1

あなたはそこからではありません。そのセカンダリxmlファイルは拡張されていないか、コンテキストビューとして設定されていないため、ボタンは存在しません。

実行できるのは、getView関数のリストのアダプターで、その行ビューを拡張することです(おそらく、行ごとに数回)。それを膨らませると、行xmlの最上位ビューのViewクラスを取得し、その上でfindViewByIDを実行できます。

于 2013-01-25T14:14:16.113 に答える