java - 初始化 View 时读取 View 的子级

标签 java android xml android-layout

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

代码:

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

关于java - 初始化 View 时读取 View 的子级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36155544/

相关文章:

java - Android Studio EditText 字段给出 null 或 0

c# - XML 中命名空间的区别

java - 为什么 Transformer 返回 &lt 和 &gt 而不是 < 和 >?

java - 使用 log4j 进行 reSTLet 日志记录

JavaFX primaryStage 删除 windows 边框?

android - 无法使用 proguard 生成签名的 apk

java - 如何使用 Java 设置 AdUnitId?

java - 使用外部绑定(bind)文件 (XJB) 将 XMLGregorianCalendar 更改为日期

java - 从 Windows 上的 C 中检测 32/64 位 Java

java - 如何使用 play-services-* 依赖项显示电话号码和电子邮件选择器对话框?