lenny
lenny

Reputation: 784

Read View's children while initializing View

This View is supposed to make a Button for each LinearLayout inside itself, and put that LinearLayout inside a ScrollView. I think the problem is that the LinearLayouts don't exist yet, since they are created AFTER initializing this view. Therefore getChildCound() returns zero. You could work around this by hard coding the number of Buttons or getting it from a XML attribute, but you can't put the LinearLayouts in the ScrollViews, when there are no LinearLayouts. Is there a way to work around this?

code:

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>

Upvotes: 0

Views: 57

Answers (2)

Konstantins Bogdanovs
Konstantins Bogdanovs

Reputation: 382

You can create custom LinearLayout inside ScrollView:

<ScrollView>
  <LinearLayout android:id="@+id/parent"/>
</ScrollView>

Then Create java class for your layout and inflate it.

See this

Upvotes: 0

Konstantins Bogdanovs
Konstantins Bogdanovs

Reputation: 382

The idea is that you need to put your logic into onLayout Something like this:

@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);
        }
    }
.......

See this

Make sure that you call child.layout() for each child inside this method.

Upvotes: 1

Related Questions