该视图应该为内部的每个LinearLayout制作一个Button,并将该LinearLayout放入ScrollView中。我认为问题在于LinearLayouts还不存在,因为它们是在初始化此视图之后创建的。因此getChildCound()返回零。您可以通过对按钮的数量进行硬编码或从XML属性中获取它来解决此问题,但是当没有LinearLayouts时,您不能将LinearLayouts放入ScrollViews中。有办法解决这个问题吗?

码:

package mika.actual;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;

import java.util.ArrayList;


public class AccordionWidget extends LinearLayout{

    public AccordionWidget(Context c, AttributeSet attrs) {
        super(c, attrs);

        final Context context = c;

        final int count = this.getChildCount();

        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.accordion);
        String[] btns = getResources().getStringArray(R.array.buttons);
        ArrayList<LinearLayout> lls = new ArrayList <> (count);

        for(int i = 0; i < count; i++){
            View child = this.getChildAt(i);
            if (child instanceof LinearLayout) {
                lls.add((LinearLayout)child);
            }
        }

        for(int i = 0; i < lls.size(); i++){

            if(btns[i] == null){
                Log.e("error: ", "Please add more Button lables to the strings.xml file.");
            }

            final Button btn = new Button(context);
            final LinearLayout ll = lls.get(i);
            final ScrollView sv = new ScrollView(context);
            final int col_pressed = a.getColor(R.styleable.accordion_backgroundColorPressed, Color.BLACK);
            final int col_unpressed = a.getColor(R.styleable.accordion_backgroundColorUnpressed, Color.YELLOW); //Black and yellow, black and yellow...


            LayoutParams btnparams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
            LayoutParams swparams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            LayoutParams llparams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            btn.setText(btns[i]);
            btn.setBackgroundColor(col_pressed);
            llparams.weight = 1f;

            btn.setLayoutParams(btnparams);
            ll.setLayoutParams(llparams);
            sv.setLayoutParams(swparams);
            ll.setOrientation(LinearLayout.VERTICAL);
            sv.setVisibility(View.GONE);

            this.addView(sv);
            this.addView(btn);
            sv.addView(ll);

            btn.setOnClickListener(new OnClickListener() {
                private boolean btnstate = false;
                @Override
                public void onClick(View v) {
                    if (btnstate) {
                        btn.setBackgroundColor(col_pressed);
                        sv.setVisibility(View.VISIBLE);
                        btnstate = true;
                    } else {
                        btn.setBackgroundColor(col_unpressed);
                        sv.setVisibility(View.GONE);
                        btnstate = false;
                    }
                }
            });
        }
        a.recycle();
    }
}


XML:

<?xml version="1.0" encoding="utf-8"?>
<mika.actual.AccordionWidget
    xmlns:accordion="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    accordion:text_color="@color/text_color"
    accordion:backgroundColorPressed="@color/button_pressed"
    accordion:backgroundColorUnpressed="@color/button_not_pressed"
    android:id="@+id/swaggy"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="yolooooo yooo"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="yolooooo yooo"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="yolooooo yooo"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="yolooooo yooo"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="yolooooo yooo"/>

    </LinearLayout>

</mika.actual.AccordionWidget>

最佳答案

想法是您需要将逻辑放入onLayout
像这样:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final Context context = c;

    final int count = this.getChildCount();

    TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.accordion);
    String[] btns = getResources().getStringArray(R.array.buttons);
    ArrayList<LinearLayout> lls = new ArrayList <> (count);

    for(int i = 0; i < count; i++){
        View child = this.getChildAt(i);
        if (child instanceof LinearLayout) {
            lls.add((LinearLayout)child);
        }
    }
.......


this

确保在此方法中为每个孩子调用child.layout()

10-04 19:16